DataMuseum.dk

Presents historical artifacts from the history of:

CP/M

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about CP/M

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download

⟦790562e34⟧ RcTekst

    Length: 192768 (0x2f100)
    Types: RcTekst
    Names: »99110141.WP«

Derivation

└─⟦7fab0c8ae⟧ Bits:30005866/disk3.imd Dokumenter i RcTekst format (RCSL 99-1-*)
    └─⟦this⟧ »99110141.WP« 

RcTekst


╱04002d4e0a00060000000003013c3100000000000000000000000000000000000000000000000000050f19232d37414b555f69737d8791ff04╱

════════════════════════════════════════════════════════════════════════
↓
┆14┆┆b3┆┆06┆┆0b┆┆05┆↓
┆b0┆┆a1┆1. INTRODUCTION↲
↲
┆b0┆┆a1┆1.1 Goals↲
↲
The principle goal of Real-Time Pascal is to be a ↓
programming tool particularly well-suited in situations ↓
characterized by the following two requirements:↲
↲
- ┆84┆the software must provide rapid response to external ↓
┆19┆┆82┆┄┄events ("real-time"),↲
- ┆84┆programmers wish to utilize the organization of software ↓
┆19┆┆82┆┄┄into parallel cooperating processes as a fundamental ↓
┆19┆┆82┆┄┄structuring tool.↲
↲
The major use of Real-Time Pascal has been and is foreseen ↓
to remain in the basic software of distributed processing ↓
systems and data communication network nodes:↲
↲
- terminal emulation,↲
- layered protocol handling,↲
- local area networking services.↲
↲
In these kinds of situations the two above-mentioned ↓
requirements are inherently present.↲
↲
The programming of end-user applications, and in particular: ↓
programming by the end user, are not goals of Real-Time ↓
Pascal. High level run-time support functions, such as a ↓
general high level input/output system, are not included in ↓
the language. However, provided suitable tools are furnished ↓
along with support for the language itself, it may prove to ↓
be well suited for applications programming as well as ↓
systems programming.↲
↲
Although Real-Time Pascal aims at low level programming it ↓
is very much a high level language. This is true in terms of ↓
syntax, in terms of programming facilities, and in ↓
particular in terms of the amount of consistency enforcement ↓
which is emboided in the language.↲
↲
┆8c┆┆83┆┆e0┆↓
Real-Time Pacal has not been designed specifically for any ↓
particular machine. However, the feasibility and usefulness ↓
of a planned implementation on the Intel iAPXn86 processor ↓
series have been absolute requirements. One type of machine ↓
dependency is built into the languageø in order that ↓
descriptive types (cf. section 3.11) be correctly ↓
implemented, the memory of the target machine must be ↓
addressable at the level of 8-bit bytes, and the ↓
significance of individual bytes within multi-byte entities ↓
(e.g. 16-bit words) must increase with increasing addresses.↲
↲
↲
┆b0┆┆a1┆1.2 Main Features↲
↲
In many respects Real-Time Pascal is, as one might ↓
anticipate, similar to standard Pascal (1, 2). The major ↓
difference is that Real-Time Pascal includes facilities for ↓
starting and controlling multiple processes as well as for ↓
the orderly synchronization and intercommunication between ↓
such processes. Features which are basic to Real-Time Pascal ↓
but well-known from standard Pascal are not discussed in ↓
this section.↲
↲
↲
┆b0┆┆a1┆1.2.1 Processes↲
↲
As in standard Pascal, a Real-Time Pascal ┆a1┆program┆e1┆ consists ↓
of declarations and definitions of data to be manipulated, ↓
and a description of actions to perform the desired ↓
manipulations. The execution of a Real-Time Pascal program ↓
is called a ┆a1┆process┆e1┆. A process is said to be an ┆a1┆incarnation┆e1┆ ↓
of the program which is executed.↲
↲
Real-Time Pascal is intended for compilation. The major ↓
ingredient of an implementationis the compiler which will ↓
transform source programs into object code executable on ↓
some target machine. Throughout this document reference is ↓
made to ┆a1┆compiletime┆e1┆, the time when a source text is being ↓
┆8c┆┆83┆┆c8┆↓
manipulated by a compiler, and ┆a1┆run-time┆e1┆, the time when a ↓
dynamic system consisting of a number of cooperating ↓
processes is operative.↲
↲
In addition to declarations of data and descriptions of ↓
actions a program (and this is where Real-Time Pascal ↓
departs from standard Pascal) may contain sub-programs, and ↓
a process may create, start and control incarnations of sub-↓
programs of the program of which it is itself an ↓
incarnation. Sub-programs may be nested to any depth. In ↓
order words a number of Real-Time Pascal programs may ↓
constitute a ┆a1┆program tree┆e1┆. The encloser relation between a ↓
program and a sub-program is carried directly over to the ↓
┆a1┆parent┆e1┆ relation that exists between a process and a ┆a1┆child┆e1┆ ↓
process which it has created. Thus the dynamic set of active ↓
processes will exhibit a control structure reflecting the ↓
nested structure of the program tree.↲
↲
An essential feature of Real-Time Pascal is that a number of ↓
special types and operations on variables of these types are ↓
directly tailored to perform syncrhonization and exchange of ↓
access to shared data between processes in a well-defined ↓
and secure fashion. In particular one important invariant is ↓
maintained a priori (i.e. without the programmer needing to ↓
worry about it): to every ┆a1┆buffer┆e1┆ there exists at any given ↓
time precisely one ┆a1┆reference┆f0┆┆e1┆, allowing at most one process ↓
to access the buffer contents. Exchange of access to a ↓
buffer is achieved by passing the (contents of the) buffer ↓
as a message via a ┆a1┆mailbox.↲
↲
The operations for process synchronization and message ↓
passing are available in Real-Time Pascal as predefined ↓
routines. This implies that an implementation of Real-Time ↓
Pascal will involve the construction of either:↲
↲
- ┆84┆a software nucleus, i.e. a small operating system, which ↓
┆19┆┆82┆┄┄performs the message passing and process synchronization ↓
┆19┆┆82┆┄┄and scheduling functions, typically in a highly dedicated ↓
┆19┆┆82┆┄┄manner, or↲
↲
┆8c┆┆83┆┆e0┆↓
- ┆84┆a run-time system providing a bridge to a general ↓
┆19┆┆82┆┄┄operating system which lends itself to supporting the type ↓
┆19┆┆82┆┄┄of process synchronization and inter-communication ↓
┆19┆┆82┆┄┄functions defined as part of Real-Time Pascal.↲
↲
An operating system to be used for the latter kind of ↓
implementation must support the execution of multiple ↓
processes either in true parallel on a single processor. The ↓
operating system must perform process scheduling; it must ↓
also support the exchange of messages via mailboxes. In ↓
general it is necessary to critically evaluate a given ↓
operating system before it is used as a foundation for an ↓
implementation of Real-Time Pascal.↲
↲
When a suitable general operating system is used to perform ↓
the Real-Time Pascal functions of process synchronization ↓
and message passing, the ability is opened up for Real-Time ↓
Pascal processes to cooperate with processes written in ↓
other, typically low-level, languages supported under that ↓
operating system. In order to make this possibility ↓
practically useful, the data formats and operating system ↓
calling sequences used by the Real-Time Pascal compiler in ↓
question must be well-documented.↲
↲
One area in which the use of other languages in conjunction ↓
with Real-Time Pascal is particularly important is the ↓
direct interaction with peripheral devices and the ↓
processing of interrupts. So-called driver processes which ↓
perform tasks of these types will always be machine ↓
dependent and may be programmed in assembler or PL/M-type ↓
languages. Consequently no input/output instructions or ↓
interrupt syncrhonization functions have been incorporated ↓
into Real-Time Pascal. It is a simple matter, however, to ↓
extend a particular implementation with these functions.↲
↲
↲

════════════════════════════════════════════════════════════════════════
↓
┆b0┆┆a1┆1.2.2 Data Typing↲
↲
Like standard Pascal, Real-Time Pascal is a stronly typed ↓
language. Types, in the abstract, provide important ↓
assitance to structured programmer thinking, and the ↓
enforcement of strong typing is a useful tool in the ↓
detection of many kinds of errors. A particular class of ↓
types, the so-called descriptive types, on the other hand, ↓
may be used in a very concrete fashion to describe the ↓
precise interpretation of bit-strings in the memory of the ↓
machine executing a Real-Time Pascal program. This feature ↓
is particularly useful when the precise representation of ↓
data is prescribed as part of the external specifications of ↓
a software project, e.g. a standard protocol for some aspect ↓
of a data communication function.↲
↲
Another feature which stands apart from the class room style ↓
of standard Pascal is that Real-Time Pascal allows the ↓
definition of families of conformant types, differing only ↓
in the values of type parameters which may determine e.g. ↓
the length of an array, but having the same structure. Types ↓
are also allowed to be dynamic, e.g. by having parameters ↓
which cannot be evaluated at compile-time. Both of these ↓
features support the construction of dynamically ↓
configurable software.↲
↲
↲
┆b0┆┆a1┆1.2.3 Data Access↲
↲
The data items manipulated by a process may be allocated as ↓
┆a1┆private┆e1┆ to the process, or they may be allocated as ┆a1┆shared┆e1┆, ↓
implying that access to the data may be shared among several ↓
processes, as described above.↲
↲
The handling of ┆a1┆variables┆e1┆ is based on the concepts of ↓
objects and types which are described in chapter 3. A ↓
private variable may be declared, in which chase allocation ↓
and deallocation of memory for the variable is performed ↓
automatically in a ┆a1┆stack┆e1┆ according to the well-known ↓
discipline for block structured languages. A declared ↓
┆8c┆┆83┆┆e0┆↓
variable is accessed directly by name. A private variable ↓
may also be allocated dynamically in the so-called ┆a1┆heap┆e1┆ by ↓
an invocation of the predefined routine new. In this case ↓
the variable must be accessed through a pointer.↲
↲
Each process has its own stack and heap, which are thus ↓
well-suited for private variables. However, a variable in ↓
the stack may be declared as shared, implying that it can ↓
only be accessed in a so-called ┆a1┆region┆e1┆. A shared variable ↓
can be made accessible to a child process as a process ↓
parameter.↲
↲
A variable is said to be ┆a1┆owned┆e1┆ by the process in whose stack ↓
or heap it is allocated. A variable may become known to ↓
processes other than the owner by being passed as a process ↓
parameter.↲
↲
Buffers are allocated neither in the stack nor in the heap ↓
of a process, but separate from both of these. Buffers are ↓
organized in ┆a1┆pools┆e1┆. a pool may contain a number of buffers ↓
of equal size.↲
↲
A buffer is not in itself a variable, but like an object it ↓
occupies a number of consecutive bytes of memory, and a ↓
buffer may be treated as a variable by superimposing a type ↓
onto it in a lock statement.↲
↲
Buffers are accessed through variables of the predefined ↓
type reference. A number of operations involving buffers are ↓
available as predfined routines taking references as ↓
parameters. In particular it is possible to build ┆a1┆buffer ↓
┆19┆┄┄┆84┆stacks┆e1┆ (not to be confused with process stacks) and ┆a1┆buffer ↓
┆19┆┄┄┆84┆chains┆e1┆.↲
↲
Associated with a buffer is a set of buffer ┆a1┆attributes┆e1┆, one ↓
of which is the buffer size, i.e. the number of bytes it ↓
occupies. The values of some of the buffer attributes are ↓
accessible, and some may also be modified. A buffer of size ↓
┆8c┆┆83┆┆c8┆↓
0, called an ┆a1┆empty buffer┆e1┆, may be used meaningfully in ↓
connection with buffer stacks, and/or for simple ↓
synchronization purposes. An empty buffer has a full set of ↓
buffer attributes. Fig. 1 gives a sketch of how memory might ↓
be organized in an implementation of Real-Time Pascal. ↓
Clearly an architecture supporting segmentation will be ↓
helpful.↲
↲
↲
┆b0┆┆a1┆1.2.4 Distributed Systems↲
↲
A principal area of intended use of Real-Time Pascal is the ↓
construction of distributed systems according to the general ↓
architectural principles described in (4).↲
↲
A resident module, in the sense of (4), may consist of a ↓
number of cooperating Real-Time Pascal processes. ↓
Intercommunication at the so-called level i, may then take ↓
place using the Real-Time Pascal facilities for inter-↓
process communication.↲
↲

════════════════════════════════════════════════════════════════════════
↓
┆06┆┆a1┆          ┆e1┆ ┆05┆┆a1┆buffers   ↲
   ↓
↲
┆a1┆          ┆e1┆               ┆a1┆          ┆e1┆ stack↲
╞	┆05┆┆a1┆          ↲
                         ┆a1┆          ┆e1┆ heap↲
┆a1┆          ┆e1┆                                        ┆a1┆┆05┆↲
code of program A        ┆a1┆          ↲
                         stack and heap↲
                         of process A             ┆a1┆          ↲
↲
↲
↲
╞	╞	╞	 ┆a1┆          ┆e1┆┆05┆┆a1┆          ↲
┆a1┆         ┆e1┆╞	╞	 ┆a1┆          ┆e1┆↲
┆a1┆↲
                         ┆a1┆          ┆e1┆               ┆a1┆ ┆05┆↲
                                                  ┆a1┆┆05┆↲
                         ┆a1┆          ↲
┆a1┆         ┆e1┆                stack and heap↲
code of program B        of process B┆82┆1            ┆81┆┆a1┆ ┆05┆↲
↲
↲
┆06┆┆a1┆         ↲
↲
┆06┆┆a1┆         ↲
↲
┆06┆┆a1┆         ↲
↲
┆06┆┆a1┆         ↲
╞	╞	╞	  stack and heap↲
╞	╞	╞	  of process B┆82┆2↲
↲
Figure 1: Example of memory organization.↲

════════════════════════════════════════════════════════════════════════
↓
To support inter-module communication (at the so-called ↓
level d) the predinfed type ┆a1┆port┆e1┆, representing the concept ↓
of port as described in (4) has been included in the ↓
language along with a set of predefined routines to perform ↓
inter-module communication (IMC) functions (5).↲
↲
Implementations may exist which support only a limited set ↓
of IMC functions or none at all.↲
↲
↲
┆b0┆┆a1┆1.2.5 Faults↲
↲
The term ┆a1┆fault┆e1┆ is used throughout the following chapters to ↓
refer to violations of semantic rules which cannot be ↓
completely enforced at compile-time, i.e. violations which ↓
can in some cases only be detected when a program is ↓
executed.↲
↲
The language allows partly programmer-defined handling of ↓
faults. By default the occurrence of a fault will cause the ↓
output of suitable diagnostic information.↲
↲
↲
┆b0┆┆a1┆1.2.6 Extensibility↲
↲
The general representation of built-in functions of the ↓
language is that of predefined routines working on ↓
parameters of predefined, and often shielded, types.↲
↲
When a desire for extensions to the defined language arises, ↓
it will be both natural and usually also easy to define such ↓
extensions in terms of one or more types and routines ↓
operating on parameters of these types. For example, a ↓
general high-level input/output system may be implemented in ↓
this way.↲
↲
The distinction between built-in functions and such ↓
extensions will not appear very sharp at all, nor is it ↓
┆8c┆┆83┆┆c8┆↓
intended to. The only missing feature will be compiler ↓
supported protection of types one might wish to shield. ↓
Supporting a larger number of shielded types, however, ↓
requires very little in the way of compiler modification, ↓
and thus a future evolution of the language, e.g. toward ↓
supporting application programming, is at least feasible.↲
↲
↲
┆b0┆┆a1┆1.3 Syntax Diagrams↲
↲
Each ┆a1┆syntax category┆e1┆ of the context-free syntax of Real-Time ↓
Pascal is defined by a ┆a1┆syntax diagram┆e1┆. A syntax diagram ↓
consists of:↲
- ┆84┆the name of the defined syntax category followed by a ↓
┆19┆┆82┆┄┄colon,↲
- arrows, which may include branching,↲
- ┆84┆indications of occurrences of syntax categories, in the ↓
┆19┆┆82┆┄┄form of rectangular boses containing the category names,↲
- language symbols enclosed in rounded boxes.↲
↲
┆a1┆Example:↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
A source text or substring of a source text is ↓
asyntactically correct occurrence of a syntax category if it ↓
┆8c┆┆83┆┆c8┆↓
can be obtained by traversing the diagram defining that ↓
category, following the arrows. When an indication of an ↓
occurrence of a syntax category is encountered (must be ↓
entered through an arrow), the traversal diagramis the ↓
sequence of lexical elements which have ultimately been ↓
encountered.↲
↲
The names of syntax categories are used frequently in the ↓
descriptionsof the semantics of language consructs to refer ↓
to particular occurrences of syntax categories. To make it ↓
clear that a sequence of words in the text is indeed a ↓
reference to such an occurrence it may be enclosed in single ↓
quotes.↲
↲
Prefixes terminated by underscores are also used in names of ↓
syntax categories to make it easier to refer to a particular ↓
occurrence of a syntax category. They have no significance ↓
in the context-free syntax. For example 'bound-type_name7 ↓
and 'parameterized-type_name' are syntactically equivalent ↓
and both defined by the diagram for 'name'. Hyphens and ↓
spaces are used exculisvely as reading aids.↲
↲
A prefix which occurs in several syntax diagrams may be ↓
understood as an indication of a context-sensitive syntax ↓
rule. Such rules, however, are all explained in the text ↓
describing the semantics of the relevant constructs.↲
↲
A complete set of syntax diagrams is collected in appendix ↓
B.↲
↲
↲
┆b0┆┆a1┆1.4 Organization of this Manual↲
↲
A rigorous definition of the Real-Time Pascal programming ↓
language is given in the following chapters. Each chapter is ↓
divided into sections, each dealing with a particular aspect ↓
of the language. The contents of a section are in general as ↓
follows:↲
↲
┆8c┆┆83┆┆d4┆↓
- introductory remarks,↲
- syntax diagrams (some sections contain no diagrams),↲
- ┆84┆description in natural language of the semantics of the ↓
┆19┆┆82┆┄┄particular part of the language,↲
- ┆84┆optional notes, where specific consequences of the syntax ↓
┆19┆┆82┆┄┄or semantics may be pointed out,↲
- examplex.↲
↲
The notes and examples do not constitute part of the ↓
definition of the language.↲
↲

════════════════════════════════════════════════════════════════════════
↓
┆b0┆┆a1┆2. LEXICAL ELEMENTS↲
↲
A Real-Time Pascal source program is a string of characters ↓
which can be (uniquely) parsed as consisting of a sequence ↓
of suitably separated lexical elements. Separators are ↓
comments and nonprinting symbols. There are five categories ↓
of lexical elements:↲
↲
- names,↲
- character literals,↲
- character strings,↲
- numbers, and↲
- language symbols.↲
↲
Of these only names are defined in terms of syntax diagrams; ↓
the others are verbally described. All language symbols, ↓
some of which are keywords similar to names, as well as som ↓
additional names, are predefined as part of the language. ↓
The remaining lexical elements are programmer-specified.↲
↲
No separator may occur within a single lexical element. At ↓
least one separator must appear between any pair of ↓
consecutive lexical elements whenever this is necessary to ↓
provide unique delimitation.↲
↲
An alphabetic character, a through z, is an occurrence of ↓
the category 'letter' which is referred to in the following. ↓
No destinction is made between the upper and lower case ↓
forms of the same letter, except in character literals or ↓
character strings.↲
↲
↲
┆b0┆┆a1┆2.1 Names↲
↲
All declared entitites, whether programs, routines, types, ↓
variables or merely constants, have a name.↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
┆8c┆┆84┆┆b4┆↓
All characters in a name are significant. However, names ↓
used in conjunction with external linking may be abbreviated ↓
in an implementation/installation dependent fashion.↲
↲
The keywords (cf. subsection 2.5.1) satisfy the syntax for ↓
'name', but are explicitly excluded from the catagory. In ↓
addition a number of routines,types and constants exist (cf. ↓
Appendix C) with predefined names, i.e. these names can be ↓
redefined.↲
↲
┆a1┆Examples:↲
↲
step  usage_count  process_117  Very_Long_Identifier_Name↲
↲
↲
┆b0┆┆a1┆2.2 Character Literals↲
↲
Character literals denote characters, which are values of ↓
the predefined type char. They are described in subsection ↓
3.4.2.↲
↲
↲
┆b0┆┆a1┆2.3 Character Strings↲
↲
Character strings denote values of string types. They are ↓
described in subsection 3.9.4.↲
↲
↲
┆b0┆┆a1┆2.4 Numbers↲
↲
A number is a sequence of digits, possibly prefixed by a ↓
radix specification. A digit is a decimal digit, 0 through ↓
9, or one of the letters A through F.↲
↲
Numbers without a radix prefix are integer numbers in ↓
standard decimal notation; they denote values of the ↓
predefined type integer, cf. subsection 3.4.3.↲
↲
┆8c┆┆83┆┆c8┆↓
Numbers prefixed with a radix specification are interpreted ↓
as follows:↲
↲
 B╞	binary, digits must be 0,1↲
 O╞	octal, digits must be 0..7↲
 D╞	decimal, digits must be 0..9↲
 H╞	hexadecimal, digits must be 0..9, A..F↲
↲
If the number of digits following the radix specificationis ↓
less than or equal to 8, for binary, or 2, for other ↓
radices, then the type of the number is the predefined ↓
machine type byte; otherwise it is word. Cf. section 3.5.↲
↲
┆a1┆Examples:↲
↲
 B1010 - a byte↲
 0777   HCAFE   D255    D37913    - four words↲
↲
↲
┆b0┆┆a1┆2.5 Language Symbols↲
↲
The predefined language symbols fall in two classes: ↓
keywords and special symbols.↲
↲
↲
┆b0┆┆a1┆2.5.1 Keywords↲
↲
Keywords are reserved names, i.e. it is illegal to use them ↓
as names in declarations. Throughout this document some ↓
keywords are rendered in small case letters and some in ↓
capitals, merely as a matter of style. The keywords are:↲
↲

╱04002d4e0a0006000000000301413100000000000000000000000000000000000000000000000000050f19232d37414b555f69737d8791ff04╱

╱04002d4e0a00060000000003013c3100000000000000000000000000000000000000000000000000050f19232d37414b555f69737d8791ff04╱
↓
AND        ARRAY     AS         BEGIN    boolean╞	 byte↲
CASE       chan      char       CONST    CONTINUELOOP  create↲
DIV        DO        DOWNTO     ELSE     END           ENDLOOP↲
EXIT       EXITLOOP  EXTERNAL   FOR      FORWARD       FUNCTION↲
GOTO       IF        IN         INSPECT  integer       link↲
LOCK       LOCKBUF   LOOP       mailbox  MOD           NOT↲
┆8c┆┆83┆┆c8┆↓
OF         OR        OTHERWISE  PACKED   pool          port↲
PROCEDURE  process   PROGRAM    RECORD   reference     REGION↲
REPEAT     SET       SHARED     SHIFT    THEN          TO↲
TYPE       typesize  unlink     UNTIL    VAR           varsize↲
WHILE      WITH      word       XOR↲
↲
↲

╱04002d4e0a00060000000003013c3100000000000000000000000000000000000000000000000000050f19232d37414b555f69737d8791ff04╱

╱04002d4e0a0006000000000301413100000000000000000000000000000000000000000000000000050f19232d37414b555f69737d8791ff04╱
↓
┆b0┆┆a1┆2.5.2 Special Symbols↲
↲
The special symbols are special graphic symbols or short ↓
sequences of such symbols. The following special symbols are ↓
defined as part of the language:↲
↲
+  -  *   <    >  <>  <=  >=  (   )   (.  .)  (:  :)↲
`  =  :=  :=:  .  ,   ;   :   .. ***  !    ?  &↲
↲
↲
┆b0┆┆a1┆2.6 Comments↲
↲
Comments may be inserted in a source program in three forms:↲
↲
1. (* comment *)↲
   ┆84┆All characters between the delimiters (* and *) are part ↓
┆19┆┆83┆┄┄of the comment, including any non-printing characters.↲
↲
2. <* comment *>↲
   ┆84┆All characters between the delimiters <* and *> are part ↓
┆19┆┆83┆┄┄of the comment, including any non-printing characters.↲
↲
3. -- comment end-of-line↲
   ┆84┆All characters from the delimiter -- up to the first ↓
┆19┆┆83┆┄┄occurence of a carriage return, line feed, or form feed ↓
┆19┆┆83┆┄┄character are part of the comment.↲
↲

════════════════════════════════════════════════════════════════════════
↓
┆b0┆┆f0┆┆a1┆Examplex:↲
↲
<* this is (* ... *) one comment *>↲
↲
(* this is -- another↲
   comment *)↲
↲
-- a third comment↲
↲
↲
┆b0┆┆a1┆2.7 Non-printing Characters↲
↲
Non-printing characters which are not part of a comment are ↓
separators on threir own. Any Real-Time Pascal compiler ↓
should allow space, tabulation, line and form feed, and ↓
carriage return characters.↲
↲
↲

════════════════════════════════════════════════════════════════════════
↓
┆b0┆┆a1┆3. TYPES AND OBJECTS↲
↲
An ┆a1┆object┆e1┆ is a data entity, manifest during the execution of ↓
a program as occupying some amount of memory. With one ↓
exception (irregular sub-objects of objects of a descriptive ↓
type, cf. section 3.11) an object always occupies an ↓
integral number of successive bytes of memory. The number of ↓
bytes is called the ┆a1┆size┆e1┆ of the object and the address of ↓
the lowest addressed byte is called the ┆a1┆address┆e1┆ of the ↓
object. The ┆a1┆value┆e1┆ of an object is at any given time ↓
represented by the bit pattern present in the part of memory ↓
occupied by the object. An object may be a declared, and ↓
thus named, constant, variable, or parameter, or it may be a ↓
temporary anonymous object which exists only during the ↓
evaluation of some expression or the execution of certain ↓
kinds of statements.↲
↲
Every object has a ┆a1┆type┆e1┆. A type comprises a set of values ↓
which may be assumed by objects of the type. A number of ↓
predefined types exist as part of the language and ↓
additional types may be defined in type declarations. In ↓
particular it is possible to define structured types. ↓
Objects of structured types are composed of ┆a1┆sub-objects┆e1┆ of ↓
other (simpler) types. All objects of a type have the same ↓
size, called the size of the type.↲
↲
Associated with a type is a set of ┆a1┆operations┆e1┆ applicable of ↓
values of the type. In the case of a structured type some of ↓
the operations provide access to the sub-objects of objects ↓
of the type.↲
↲
An important relation between types is ┆a1┆compatibility┆e1┆ which ↓
playes a key role in determining when the assignment, ↓
explicit or by parameter passing, of a value to an object of ↓
some type is legal.↲
↲
The structural aspects of a type are always obtainable from ↓
(the text of) the definition. However, the size of a type ↓
┆8c┆┆83┆┆c8┆↓
may be given by expressions which in general can only be ↓
evaluated at tun-time. A type is said to be ┆a1┆established┆e1┆ when ↓
all expressions in the definition are evaluated and the ↓
actual layout of objects of the type and thus also the ↓
representation of values of the type, are determined. A type ↓
in whose definition all expressions are constant expressions ↓
and which can therefore be established at compile-time, is ↓
called a ┆a1┆static┆e1┆ type.↲
↲
All tpes, whether explicitly specified or implicitly given ↓
by the context, are ┆a1┆classified┆e1┆ as:↲
↲
- ordinal types,↲
- machine types,↲
- set types,↲
- pointer types,↲
- shielded types, or↲
- structured types.↲
↲
Each class of types is described in a separate section of ↓
this chapter.↲
↲
The language includes no "real" types. It is a simple matter ↓
to extend the language or an implementation with a class ↓
containing one or more real types.↲
↲
Pointer types and shielded types are called ┆a1┆protected┆e1┆ types. ↓
The same is true of certain structured types, cf. section ↓
3.9. Protected types cannot be used in conjunction with ↓
retyping (type conversion) in with statements.↲
↲
↲
┆b0┆┆a1┆3.1 Specification of Types↲
↲
Type specifications, which include type definitions, are ↓
used in type declarations, in object declarations, in with ↓
statements, and in the formal parameter lists of routine and ↓
program headings and of declarations of parameterized types. ↓
┆8c┆┆83┆┆c8┆↓
The forms of type specification which may occur differ ↓
depending on the use.↲
↲
The form of type specification used in type declarations is ↓
called a defining type specification. This form rules out ↓
alias types, i.e. the definition of a named type simply by ↓
reference to another (bound) type name.↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
The form of type specification most commenly used, e.g. in ↓
object declarations, in with statements, and in formal type ↓
parameter lists, is called a common type specification. This ↓
form covers all types with no unbound parameters.↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
An augmented form of type specification is used in formal ↓
parameter lists of routines and programs where unbound ↓
parameterized types are allowed.↲
↲
↲
↲
↲
↲
↲
↲
↲
┆8c┆┆83┆┆e0┆↓
A type definitionis the ultimate definition of any type ↓
which is not predefined.↲
↲
↲
↲
↲
↲
↲
↲
The form 'defined type' may be used in the specification of ↓
a type as either predefined or defined, bound, and named.↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
The missing details in the above description are given in ↓
the following sections:↲
↲
┆a1┆syntactic category            section number↲
bound-type_name╞	╞	3.2↲
parameterized-type_name╞	╞	3.2↲
parameterized-type binding╞	3.3↲
ordinal-type definition╞	   ╞	3.4↲
predifined ordinal type ╞	3.4↲
machine type╞	╞	╞	3.5↲
set-type definition╞	╞	3.6↲
pointer-type definition╞	╞	3.7↲
shielded type╞	╞	╞	3.8↲
structured-type definition╞	3.9↲
↲

════════════════════════════════════════════════════════════════════════
↓
┆a1┆Note:↲
Of the six classes of types machine types are shielded types ↓
can only be predefined.↲
↲
↲
┆b0┆┆a1┆3.2 Declaration of Types↲
↲
Types may be named and defined in type declarations:↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
The rules for defining types allow several types of use of ↓
(forward, bound, or parameterized) type names in 'defining ↓
type specifications'. However, no type name may be used on ↓
the right hand side of a 'single type declaration' until it ↓
has been introduced in a preceding declaration. In ↓
particular no type name may be used in its own 'defining ↓
type specification'.↲
↲
A 'forward-type_name' may only be used in the definitionof ↓
pointer types and for every 'forward type_name' occurring in ↓
a 'type declaration', the same name must be given a ↓
definition (bound or parameterized) later within the ↓
declaration part of the same block.↲
↲
┆8c┆┆83┆┆e0┆↓
These rules exclude recursion in the definition of ↓
structured types, but allow objects of a structured type to ↓
contain pointers to objects of the same type and also allow ↓
mutual pointers between several structured types.↲
↲
A single type declaration without parameters associates the ↓
'bound-type_name' with the type specified on the right hand ↓
side, called ┆a1┆the defining type┆e1┆. That is, when the 'bound-↓
type_name' is itself used as a type specification, e.g. in ↓
the declaration of an object, the type thus specified ↓
inherits the value set, the representation of values, the ↓
object layout, the applicable operations and the ↓
classification of the defining type. However, the type ↓
specified by the 'bound-type_name' is ┆a1┆not┆e1┆ compatible with ↓
the defining type. An exception to the latter rule occurs ↓
when the defining type is a set type (cf. 3.10). The ↓
defining type is established when the type declaration is ↓
elaborated (cf. chapter 6).↲
↲
A parameterized 'single type declaration' introduces the ↓
'parameterized-type_name' as denoting a family of mutually ↓
conformant types. The 'formal type parameters', i.e. the ↓
'type-parameter_names' may be used on the right hand side of ↓
the declaration. The types specified for formal type ↓
parameters must be ordinal types. Specification of a ↓
particular type in a parameterized family of types is ↓
described in the next section. No type is established when a ↓
parameterized type declaration is elaborated.↲
↲
A typesize call is similar in form to a function call, but ↓
the "parameter" is the name of a type. The construct allows ↓
the size of a type to be used in computations.↲
↲
↲
↲
↲
The 'bound-type_name' must be the name of a bound (not ↓
parameterized) type. The value of a typesize call is the ↓
┆8c┆┆83┆┆c8┆↓
size (number of bytes) of the named type as computed when ↓
the type was established. The type of a typesize call is ↓
integer.↲
↲
┆a1┆Example:↲
↲
TYPE↲
  ptr_type;  -- forward announcement↲
  bound_type=ARRAY(1..10) OF integer;↲
  rec_type=RECORD               -- Note:↲
    f1: bound_type;             -- type of f1 not compatible↲
    f2: ARRAY(1..10) OF integer -- with type of f2↲
  END(*RECORD*);↲
  ptr_type= `rec_type;↲
  mask_type= PACKED ARRAY(1..typesize(bound_type)) OF byte↲
↲
↲
┆b0┆┆a1┆3.3 Parameterized Types↲
↲
A family of parameterized types may be defined in a type ↓
declaration (see the preceding section). A particular type ↓
in such a family, called a ┆a1┆bound parameterized type┆e1┆, is ↓
obtained by binding values to the formal type parameters.↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
The 'parameterized-type_name' must occur in a preceding ↓
parameterized type declaration, i.e. it must denote a type ↓
family. The number of formal parameters in this declaration ↓
must equal the number of 'actual type parameters', and each ↓
┆8c┆┆83┆┆c8┆↓
actual parameter must be assignable to the type of the ↓
corresponding formal parameter.↲
↲
The type specified by a 'parameterized type binding' is ↓
established according to the right hand side of the ↓
parameterized type declaration, i.e. the defining type ↓
specification, after all occurrences of the formal type ↓
parameters have been replaced with the values of the ↓
corresponding actual parameters. The properties of the ↓
defining type are inherited in the same fashion as in the ↓
case of a 'bound-type_name', cf. the preceding section.↲
↲
The actual parameter values used to establish a bound ↓
parameterized type are attached to objects of the type. The ↓
parameter values are accessible whenever the object to which ↓
they are attached is visible.↲
↲
↲
↲
↲
↲
The type of the denoted object must be a bound parameterized ↓
type. The 'type-parameter_name' must occur among the 'formal ↓
type parameters' of this type. The type of a 'selected type ↓
parameter' is the (ordinal) type specified for the 'type-↓
parameter_name' and its value is the value of the ↓
corresponding actual parameter as evaluated when the object ↓
type was established.↲
↲

════════════════════════════════════════════════════════════════════════
↓
┆a1┆Example:↲
TYPE↲
  column(rows: 1..100)= ARRAY(1..rows) OF integer;↲
  matrix(rows: 1..100)= ARRAY(1..rows) OF column(rows);↲
  matrix_10= matrix(10);↲
  ...↲
PROCEDURE invert(a:matrix);↲
VAR↲
  local_copy: matrix(a!rows);↲
  ...↲
  FOR i:=1 TO a!rows DO↲
    ...↲
↲
↲
┆b0┆┆a1┆3.4 Ordinal Types↲
↲
Ordinal types are abstract types. For any ordinal type there ↓
exists a one-to-one mapping from the set of values of the ↓
type onto a finite interval of the integral numbers, ↓
yielding the ┆a1┆ordinal value┆e1┆ corresponding to each value of ↓
the type. It follows that the value set of an ordinal type ↓
is ordered by ordinal value and that every such value set ↓
has a first and a last element. By the ordering, every ↓
value, except the last one, has a ┆a1┆successor┆e1┆ and every value, ↓
except the first one, has a ┆a1┆predecessor┆e1┆. Similarly, the ↓
relations ┆a1┆greater than┆e1┆ and ┆a1┆smaller than┆e1┆ are defined for ↓
pairs of values by the ordering.↲
↲
The relational operators which produce results of the ↓
predefined type boolean apply to pairs of operands of any ↓
ordinal type. i.e. the two operands must be of the same ↓
ordinal type. Let oleft and oright denote the ordinal values ↓
of left and right operand, respectively. The relational ↓
operators are then defined in the following table:↲
↲

╱04002d4e0a0006000000000301413100000000000000000000000000000000000000000000000000050f19232d37414b555f69737d8791ff04╱

╱04002d4e0a00060000000003013c3100000000000000000000000000000000000000000000000000050f19232d37414b555f69737d8791ff04╱
↓

════════════════════════════════════════════════════════════════════════
↓
┆a1┆operator  result┆05┆┆05┆↲
 =╞	      true if oleft equals oright, otherwise false↲
 <>╞	      false if oleft equals oright, otherwise true↲
 >╞	      true if oleft is greater than oright, otherwise false↲
 <=╞	      false if oleft is greater than oright, otherwise true↲
 <╞	      true if oleft is smaller than oright, otherwise false↲
 >=╞	      false if oleft is smaller than oright, otherwise true↲
↲

╱04002d4e0a00060000000003013c3100000000000000000000000000000000000000000000000000050f19232d37414b555f69737d8791ff04╱

╱04002d4e0a0006000000000301413100000000000000000000000000000000000000000000000000050f19232d37414b555f69737d8791ff04╱
↓
For every ordinal type otype, there exist theree predefined ↓
functions as described below:↲
↲
FUNCTION succ(v: otype): otype↲
The result of a call of succ is the successor of the value ↓
of the parameter v, except if this value is the last one, in ↓
which case the call causes a fault.↲
↲
FUNCTION pred(v: otype): otype↲
The result of a call of pred is the predecessor of the value ↓
of the parameter v, except if this value is the first one, ↓
in which case the call causes a fault.↲
↲
FUNCTION ord(v: otype): integer↲
The result of a call of ord is the ordinal value ↓
corresponding to the value of the parameter v.↲
↲
There are three predefined ordinal types and two ways to ↓
define new ordinal types. These are described in detail in ↓
the following subsections.↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲

════════════════════════════════════════════════════════════════════════
↓
┆b0┆┆a1┆3.4.1 The Type Boolean↲
↲
The type boolean has two values which correspond to truth ↓
values and are denoted by the predefined value names ┆a1┆false┆e1┆ ↓
and ┆a1┆true┆e1┆. The ordinal values are: ord(false)=0 and ↓
ord(true)=1.↲
↲
There are two dyadic operators which take boolean operands ↓
and produce a boolean result: AND and OR. There is one ↓
monadic operator which takes a boolean operand and produces ↓
a boolean result: NOT. The results produced by these ↓
operators are in accordance with standard logical truth ↓
tables for conjunction, disjunction and negation, ↓
respectively. In addition the dyadic operator XOR is ↓
provided for boolean operands. Its result, which is also ↓
boolean, is defined by the formula↲
   b1 XOR b2=(b1 AND NOT b2) OR (NOT b1 AND b2).↲
↲
↲
┆b0┆┆a1┆3.4.2 The Type Char↲
↲
the values of type char are characters belonging to a ↓
character set derived from ISO-646 (3), i.e. an ASCII-like ↓
character code set.↲
↲
The ordinal values of the type char span the interval ↓
0..255. The characters with the ordinal values 0..32 are ↓
denoted by the predefined value names NUL, SOH, STX, ETX, ↓
EOT, ENQ, ACK, BEL, BS, HT, LF, VT, FF, CR, SO, SI, DLE, ↓
DC1, DC2, DC3, DC4, NAK, SYN, ETB, CAN, EM, SUB, ESC, FS, ↓
GS, RS, US, SP. The character with the ordinal value 127 is ↓
denoted by the predefined value name DEL. The characters ↓
with ordinal values in the range 32..126 are graphic ↓
charcters and are denoted by character literals, i.e. the ↓
graphic symbol (letter, digit etc.) in question, between ↓
single quotes. The set of available graphic characters and ↓
the corresponding ordinal values is implementation and/or ↓
installation dependent. No notation exists for characters ↓
with ordinal values in the range 128..255.↲
↲
┆8c┆┆83┆┆e0┆↓
The graphic character symbols supported by an ↓
implementation/installation may also be used in character ↓
strings (cf. subsection 3.9.4).↲
↲
There exists a predefined function which yields a character ↓
result:↲
↲
FUNCTION chr(n: 0..255): char↲
The result of a call of chr is the character whose ordinal ↓
value equals the value of the parameter n.↲
↲
┆a1┆Example:↲
CONST  single_quote=''';↲
TYPE   small_letter='a'..'z'↲
↲
↲
┆b0┆┆a1┆3.4.3 The Type Integer↲
↲
The values of type inteer are integral numbers. The ordinal ↓
value of such a number is the number itself. The range of ↓
the type integer, i.e. the interval spanned by its values is ↓
implementation dependent. Positive integer values are ↓
denoted by integer numbers, cf. section 2.4.↲
↲
There are five dyadic operators which take integer operands ↓
and produce integer results:↲
↲
┆a1┆operator  description┆05┆↲
  +╞	      addition↲
  -       subtraction↲
  *       multiplication↲
 DIV      integer division (quotient truncated toward zero)↲
 MOD      remainder of integer division, i.e.↲
          a MOD b = a-b*(a DIV b)↲
↲
+ and - may also be used as monadic operators, implying an ↓
implicit left operand with value 0. When the result produced ↓
by an arithmetic operation falls outside the range of ↓
┆8c┆┆83┆┆c8┆↓
integer values supported by the implementation a fault ↓
occurs.↲
↲
The result of the predefined function abs:↲
↲
FUNCTION abs(n: integer): 0..maxint↲
is the absolute value of the parameter value. If this value ↓
falls outside the supported range the call causes a fault.↲
↲
The predefined value names maxint and minint denote the ↓
largest and the smallest integer value, respectively, ↓
supported by the implementation.↲
↲
↲
┆b0┆┆a1┆3.4.4 Enumeration Types↲
↲
An enumeration type is defined by explicitly naming its ↓
values:↲
↲
↲
↲
↲
↲
The names given int he definition are used to denote the ↓
values of the type thus defined. Consider an enumeration ↓
type defined as (e┆82┆0┆81┆, e┆82┆1┆81┆, ..., e┆82┆n┆81┆). This type has precisely ↓
n+1 distinct values with ordinal values in the interval ↓
0..n. The ordinal value corresponding to e┆82┆i┆81┆ is i, for ↓
i=0,1,...,n.↲
↲
┆a1┆Example:↲
TYPE  colours= (red, blue, green, yellow, pink)↲
↲
↲
┆b0┆┆a1┆3.4.5 Subrange Types↲
↲
a subrange specifies a type compatible with an existing ↓
type, but with a constrained range of values:↲
↲
↲
↲
↲
↲
┆8c┆┆84┆┆84┆↓
The lower and upper bound expressions must be of the same ↓
ordinal type, called the ┆a1┆base type┆e1┆ of the defined subrange ↓
type. The bounds are evaluated when the subrange type is ↓
established.↲
↲
The number of elements in the value set of the subrange is ↓
ord(upper bound)-ord(lower bound)+1. the number may be zero ↓
in which case the subrange is empty, but it may not be ↓
negative. In the latter case a fault occurs.↲
↲
The same set of operators and predefined functions apply to ↓
values of the subrange type as to values of the base type, ↓
but objects of the subrange type are constrained to assume ↓
values in the range between the lower and upper bound values ↓
(inclusively).↲
↲
┆a1┆Note┆e1┆:↲
A subrange definition is the only place where an expression ↓
can occur in a type definition. Thus all dynamic types are ↓
built from subranges. Conversely, if all expressions in the ↓
subrange definitions of a type definition are constant ↓
expressions, then the defined type is static.↲
↲
┆a1┆Example┆e1┆:↲
TYPE↲
  pos_int= 0..maxint;↲
  neg_int= minint..-1;↲
  codes= (nocode, ..., dummy_last_code);↲

╱04002d4e0a0006000000000301443100000000000000000000000000000000000000000000000000050f19232d37414b555f69737d8791ff04╱

╱04002d4e0a00060000000003013c3100000000000000000000000000000000000000000000000000050f19232d37414b555f69737d8791ff04╱
↓
  conv_table= ARRAY(succ(nocode)..pred(dummy_last_code)) OF codes↲

╱04002d4e0a00060000000003013c3100000000000000000000000000000000000000000000000000050f19232d37414b555f69737d8791ff04╱

╱04002d4e0a0006000000000301443100000000000000000000000000000000000000000000000000050f19232d37414b555f69737d8791ff04╱
↓
↲
↲
┆b0┆┆a1┆3.5 Machine Types↲
↲
Machine types allow a style of programming in which the ↓
machine instructions to be executed are specified in a very ↓
direct manner.↲
↲
┆8c┆┆83┆┆bc┆↓
Only predefined machine types exist. The repertoire of ↓
machine types depends on the implementation. However, tye ↓
types ┆a1┆byte┆e1┆ (8-bit quantity) and ┆a1┆word┆e1┆ (16-bit quantity) are ↓
mandatory.↲
↲
Values of machine types are denoted by numbers with a radix ↓
specification, cf. section 2.4.↲
↲
The operators applicable to machine types are intended to ↓
translate directly into machine instructions. Machine ↓
dependent extensions may therefore occur. The following ↓
operators are mandatory:↲
↲
┆8c┆┆81┆┆9c┆↓
┆0e┆↓
┆a1┆operator left op. right op. result description┆05┆↲
 +╞	     byte     byte      byte   unsigned addition↲
 +       word     byte      word   unsigned addition↲
 +       byte┆07┆    word      word   unsigned addition↲
 +╞	     word┆07┆    word      word   unsigned addition↲
 -       byte     byte      byte   unsigned subtraction↲
 -       word     byte      word   unsigned subtraction↲
 -       byte     word      word   unsigned subtraction↲
 -       word     word      word   unsigned subtraction↲
 *       byte     byte      word   unsigned multiplication↲
 *       word     byte      word   unsigned multiplication↲
 *       byte     word      word   unsigned multiplication↲
 *       word     word      word   unsigned multiplication↲
 DIV     byte     byte      byte   unsigned division↲
 DIV     word     byte      word   unsigned division↲
 DIV     byte     word      byte   unsigned division↲
 DIV     word     word      word   unsigned division↲
 MOD     byte     byte      byte   unsigned remainder↲
 MOD     word     byte      word   unsigned remainder↲
 MOD     byte     word      byte   unsigned remainder↲
 MOD     word     word      word   unsigned remainder↲
 AND     byte     byte      byte   bitwise logical and↲
 AND     word     word      word   bitwise logical and↲
 OR      byte     byte      byte   bitwise logical or↲
 OR      word     word      word   bitwise logical or↲
 XOR     byte     byte      byte   bitwise exclusive or↲
 XOR     word     word      word   bitwise exclusive or↲
 NOT     none     byte      byte   bitwise negation↲
 NOT     none     word      word   bitwise negation↲
 SHIFT   byte     integer   byte   logical shift toward more↲
 SHIFT   word     integer   word   significant positions↲
┆0f┆↓
↲
For arithemtic operations values of machine types are ↓
treated as unsigned binary numbers. There is no checking for ↓
overrun, however division by zero (DIV or MOD) will cause a ↓
fault.↲
↲
┆8c┆┆83┆┆bc┆↓
There are predefined procedures to increment and decrement ↓
variables of machine types (by 1, modulo 2┆81┆n┆82┆, where n is the ↓
number of bits used for the type):↲
↲
PROCEDURE inc(VAR v: mtype)↲
PROCEDURE dec(VAR v: mtype)↲
where mtype may be any machine type.↲
↲
Also for every machine type mtype there is a predefined ↓
function:↲
↲
FUNCTION int(v: mtype): integer↲
which yields the (implementation dependent) value obtained ↓
by extending (by zero bits) or truncating the value of the ↓
parameter v to the number of bits used to represent integers ↓
and then interpreting the resulting bit pattern as an ↓
integer value.↲
↲
The inverse functions are also predefined:↲
↲
FUNCTION byt (v: integer): byte↲
A call of byt extracts the 8 least significant bits from the ↓
(implementation dependent) integer representation.↲
↲
FUNCTION wrd (v: integer): word↲
A call of wrd extracts the 16 least significant bits from ↓
the (implementation dependent) integer representation.↲
↲
Moreover, two values of the same machine type may be ↓
compared, using the relational operators which are described ↓
in section 3.4. Comparison applies to the unsigned binary ↓
values.↲
↲
↲
┆b0┆┆a1┆3.6 Set Types↲
↲
The set of values of a set type is the power set of the set ↓
of values of some ordinal type, called the element type of ↓
┆8c┆┆83┆┆c8┆↓
the set type. The available operators for sets correspond to ↓
the standard operators of mathematical set theory.↲
↲
↲
↲
↲
↲
The common type specification specifies the element type ↓
which must be an ordinal type.↲
↲
Values of set types are denoted by lists of set elements.↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
All expressions occurring in a 'set denotation' must be of ↓
the same ordinal type. The type of the 'set denotation' is a ↓
set type whose element type is the type of the expressions.↲
↲
The value of a 'set denotation' is evaluated by evaluating ↓
all the expressions. Their values determine the members of ↓
the set value. When an 'element interval' occurs all values ↓
in the closed interval from the value of 'lower_expression' ↓
to the value of 'uipper_expression' are members. If the ↓
value of 'lower-expression' is greater than the value of ↓
'upper-expression' the interval is empty.↲
↲
When no expressions are present in a 'set denotation', i.e. ↓
(..), the value is the empty set. The empty set may occur ↓
whereever an operator of a set type is required. Occurring ↓
as an expression on its own, the empty set is assignable to ↓
any set type.↲
↲
┆8c┆┆83┆┆e0┆↓
The operators applicable to values of set types are ↓
described in the following table, where st means some set ↓
type, et means the element type of st, lop means left ↓
operand, and rop means right operand. Notice that multiple ↓
occurrences of st in any one line of the table refer to ↓
compatible set types.↲
┆0e┆↓
↲
oper-   type of   type of   type of    ↲
┆a1┆ator    lop       rop       result     result┆05┆↲
 +       st        st         st       lop rop↲
 *       st        st         st       lop rop↲
 -       st        st         st       lop rop↲
 IN      et        st       boolean    true if lop rop,↲
         ╞	╞	╞	     false otherwise↲
 <=      st        st       boolean    true if lop rop↲
╞	╞	╞	╞	     false otherwise↲
 >=      st        st       boolean    true if rop lop,↲
╞	╞	╞	╞	     false otherwise↲
 =       st        st       boolean    true if lop rop↲
╞	╞	╞	╞	     and rop lop,↲
 ╞	╞	╞	 ╞	     false otherwise↲
 <>      st        st       boolean    NOT lop=rop↲
┆0f┆↓
↲
┆a1┆Note:↲
There is no operator to test for strong set inclusion.↲
↲
┆a1┆Examples:↲
  digits= (. '0'..'9' .)↲
  letters= (. 'a'..'z', 'A'..'Z' .)↲
↲
↲
┆b0┆┆a1┆3.7 Pointer Types↲
↲
The values of a pointer type are NIL (no pointer) and ↓
pointers to heap-allocated variables of a specified type, ↓
called the base type of the pointer type. A pointer may be ↓
used to access the variable it points to.↲
↲
↲
↲
↲
┆8c┆┆83┆┆ec┆↓
The common type specification specifies the base type of the ↓
defined pointer type. The initial value of a pointer ↓
variable is NIL, i.e. it does not point to any variable.↲
↲
A variable accessed through a pointer is called a designated ↓
variable.↲
↲
↲
↲
↲
The type of the denoted object must be a pointer type. The ↓
type of the designated variable is the base type of this ↓
pointer type. If the value of the denoted pointer object is ↓
NIL a fault occurs when an attempt is made to access the ↓
designated variable.↲
↲
The comparison operators = and <> may be applied to pairs of ↓
operands of compatible pointer types. The result produced by ↓
the = operator is true if both pointers designate the same ↓
object, or if both have value NIL. Otherwise it is false. ↓
The result produced by the <> operator is the negation of ↓
the result of =.↲
↲
There is a predefined function to test whether a pointer, of ↓
any pointer type ptrtype, is NIL.↲
↲
FUNCTION nil(ptr: ptrtype): boolean↲
The result of a call of nil is true if the value of the ↓
parameter is NIL and false otherwise.↲
↲
A variable is allocated on the heap and a pointer to it ↓
assigned to a pointer variable by a call of the predefined ↓
procedure new, where the parameter type ptrtype may be any ↓
pointer type.↲
↲
PROCEDURE new(VAR ptr: ptrtype)↲
A call of new causes memory for a variable of the base type ↓
of the type of the parameter ptr to be allocated on the heap ↓
┆8c┆┆83┆┆c8┆↓
of the calling process. If an initial value is defined for ↓
the variable or any components of it, the initialization ↓
takes place immediately after allocation. The value of the ↓
parameter becomes a pointer to the allocated variable.↲
↲
┆a1┆Example:↲
TYPE↲
  comp; comp1_type; -- forward declarations↲
  comp1_type= RECORD↲
    number: integer;↲
    comp1_chain: `comp1_type;↲
    comp_chain: `comp↲
  END(*RECORD*);↲
  comp= ARRAY(x..y) OF `comp1_type;↲
VAR↲
  structure_start: `comp;↲
  ...↲
  new(structure_start);↲
  new(structure_start`(X));↲
  new(structure_start`(x)`.comp1_chain)↲
  ...↲
↲
↲
┆b0┆┆a1┆3.8 Shielded Types↲
↲
Shielded types are used in conjunction with control of ↓
offspring processes and with inter-process and inter-module ↓
communication. In order that the integrity of buffers and of ↓
the data structures needed to administer muliple cooperating ↓
processes be preserved it is only possible to manipulate ↓
objects of shielded types by means of predefined routines. ↓
Accordingly, details of the representation of these types ↓
are not part of the reference definition of the language. ↓
Only predefined shielded types exist, six in all.↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
┆8c┆┆84┆┆84┆↓
Constants of shielded types do not exist. Variables of ↓
shielded types, except reference, can only be declared at ↓
the outer block level of a program, cf. subsection 6.2.1.↲
↲
An object of type process may be used to control a child ↓
process, i.e. an incarnation of a sub-program. The value of ↓
a process object is either NIL or a reference to a child ↓
process, the initial value being NIL. Process objects may be ↓
manipulated by the predefined routines create, start, stop ↓
and remove, as described in chapter 9.↲
↲
The predefined function nil may be used to test whether a ↓
process variable has value NIL.↲
↲
FUNCTION nil(VAR pr: process): boolean↲
The result of a call of nil is true if the value of the ↓
parameter pr is NIL, and false otherwise.↲
↲
An object of type mailbox may be used to transfer access to ↓
a buffer stack from one process to another, using the ↓
predefined routines signal, wait and return, as described in ↓
chapter 9. The initial state of a mailbox is passive.↲
↲
An object of type port may be used in conjunction with ↓
intermodule communication as described in chapter 11. The ↓
initial state of a port is closed.↲
↲
Buffers are allocated using pools and accessed by means of ↓
objects of type reference. The value of a reference to a ↓
buffer stack, called the ┆a1┆designated stack┆e1┆. The top buffer of ↓
the designated stack is called the ┆a1┆designated buffer┆e1┆. Buffer ↓
stacks, and the predefined procedures push and pop working ↓
on them, are described in detail in chapter 10.↲
↲
The predefined function nil may be used to test whether a ↓
reference is NIL.↲
↲
FUNCTION nil(VAR ref: reference): boolean↲
┆8c┆┆83┆┆c8┆↓
The result of a call of nil is true if the value of ref is ↓
NIL, and false otherwise.↲
↲
Every buffer has fourteen attributes which are present even ↓
if the buffer is empty:↲
↲
- home pool: the pool to which the buffer belongs,↲
- ┆84┆return address: mailbox to which the buffer may be ↓
┆19┆┆82┆┄┄returned,↲
- ┆84┆u1, u2, u3, u4: objects of type 0..255 which may be read ↓
┆19┆┆82┆┄┄and written,↲
- size of the buffer, i.e. number of bytes,↲
- ┆84┆offset, top, byte count: objects of type 0..maxint which ↓
┆19┆┆82┆┄┄may be read and written; they describe the data area of ↓
┆19┆┆82┆┄┄the buffer, see below,↲
- ┆84┆event kind: indicates how and why the buffer was placed in ↓
┆19┆┆82┆┄┄the mailbox from which it has last been received or that ↓
┆19┆┆82┆┄┄the buffer was removed from a pool; see details under the ↓
┆19┆┆82┆┄┄predefined function eventkind below,↲
- ┆84┆connection index, credit count, reason: used in ↓
┆19┆┆82┆┄┄conjunction with IMC functions, cf. chapter 11.↲
↲
The values of the buffer attributes offset and top define an ↓
area within the buffer, called the ┆a1┆data area┆e1┆, which ↓
comprises the (byte) locations from offset through top-1 ↓
relative to the beginning of the buffer.↲
↲
╞	buffer↲
╞	   ┆a1┆                               ↲
       ┆a1┆!    ! data area !            !↲
           offset       top↲
↲
The byte count attribute is used to indicate the size of a ↓
unit of data which is located from the beginning of the data ↓
area, but which does not necessarily occupy the whole data ↓
area.↲
↲
┆8c┆┆83┆┆bc┆↓
In order for the data area description to be consistent, ↓
offset must be less thanor equal to top, which in turn must ↓
be less than or equal to the size of the buffer. In ↓
particular, if the buffer is empty, all three attributes ↓
must be zero.↲
↲
In a buffer stack the size and data area description ↓
attributes of the top buffer will refer to the top non-empty ↓
buffer, cf. section 10.1.↲
↲
The concept of data area is used in conjunction with the IMC ↓
functions, cf. chapter 11, and is also intended as a basis ↓
for the establishment of practical conventions for the use ↓
of the language.↲
↲
FUNCTION releasepool)VAR p: pool;↲
         no_of_bufs: 1..maxint): 0..maxint↲
↲
The number of buffers indicated by the value of no_of_bufs ↓
are released from the pool p and become free memory. If the ↓
requested number of buffers is not present in the pool fewer ↓
buffers may be released. The actual number of released ↓
buffersis returned as the result of the function call.↲
↲
A buffer is taken out from a pool by a call of the ↓
predefined procedure getbuf:↲
↲
PROCEDURE getbuf(VAR p: pool; VAR ra: mailbox; VAR r: ↓
          reference)↲
↲
At the time of call the value of the parameter r must be ↓
NIL, otherwise a fault occurs. If the pool p is empty, i.e. ↓
all buffers have been removed, the calling process will wait ↓
until a buffer becomes available. This occurs when a buffer ↓
is put back to the pool by another process (call of putbuf, ↓
see below), or when additional memory is allocated for the ↓
pool (call of allocpool, see above). When severalprocesses ↓
attempt to take out buffers from an empty pool waiting takes ↓
place in a FIFO queue.↲
↲
┆8c┆┆83┆┆e0┆↓
When a buffer i available it is removed from the pool, its ↓
return address becomes the mailbox indicated by the ↓
parameter ra, and r will designate a buffer stack consisting ↓
only of the removed buffer.↲
↲
When a buffer has just been removed from its home pool its ↓
data area will be the whole buffer, i.e. offset=zero and ↓
top=size of the buffer. The attributes u1, u2, u3, u4 and ↓
byte count will all be zero. The value of the event kind ↓
attribute will be not_event, indicating the buffer does not ↓
represent a system event.↲
↲
It is possible to specify a maximum time which a process is ↓
willing to wait for a buffer. This can be done by calling ↓
getbufdelay instead of getbuf, cf. subsection 9.2.2.↲
↲
A buffer is put back in its home pool by a call of the ↓
predefined procedure putbuf:↲
↲
PROCEDRUE putbuf(VAR r: reference)↲
At the time of call the parameter must not be locked (cf. ↓
section 5.9), and its value must not be NIL, nor may the ↓
designated stack contain more than one buffer; otherwise a ↓
fault occurs. The buffer is put back in its home pool, and ↓
the value of r becomes NIL.↲
↲
It can be tested whether a buffer belongs to a particular ↓
pool.↲
↲
FUNCTION hometest(VAR p: pool; VAR ref: reference): boolean ↓
The value of ref must not be NIL when hometest is called. If ↓
it is, a fault occurs. The result of a call of hometest is ↓
true if p is the home pool of the buffer designated by ref, ↓
otherwise it is false.↲
↲
The event kind attribute of a buffer may be read in order to ↓
determine the kind of event which the buffer represents.↲
↲
┆8c┆┆83┆┆c8┆↓
FUNCTION eventkind(VAR r: reference): event_type↲
↲
If eventkind is called with a parameter with value NIL a ↓
fault occurs, otherwise the result is the value of the event ↓
kind attribute of the designated buffer. The result type is ↓
the predefined enumeration type↲
↲
  event_type=(not_event, message_event, answer_event↲
╞	╞	process_removed, port_closed, disconnected,↲
╞	╞	letter_sent, letter_arrived, local_connect,↲
╞	╞	remote_connect, reset_indication, ↓
╞	╞	reset_completion, credit, data_sent, ↲
╞	╞	data_arrived, data_overrun, dummy_letter,↲
╞	╞	dummy_lcnct, dummy_rcnct, dummy_rindic,↲
╞	╞	dummy_rcmpl, dummy_credit, dummy_sent,↲
╞	╞	dummy_arrived).↲
↲
The value not_event indicates the buffer thas been obtained ↓
from a pool or its event kind has been reset. The value ↓
message_event indicates the buffer has been signalled from a ↓
process, cf. subsection 9.2.2. The value answer_event ↓
indicates the buffer has been returned by a process, cf. ↓
subsection 9.2.2. The value process_removed indicates the ↓
buffer has been returned from a process which was removed, ↓
cf. section 9.1. The remaining values indicate IMC events, ↓
cf. chapter 11.↲
↲
The only way a process can modify the event kind attribute ↓
of a buffer while retaining access is by resetting it.↲
↲
PROCEDURE resetevent(VAR r: reference)↲
↲
If resetevent is called with a parameter with value NIL a ↓
fault occurs, otherwise the value of the event kind ↓
attribute of the designated buffer becomes not_event.↲
↲
The u-attributes of a buffer may be read using the following ↓
four predefined functions:↲
↲
┆8c┆┆83┆┆d4┆↓
FUNCTION u1(VAR r: reference): 0..255↲
FUNCTION u2(VAR r: reference): 0..255↲
FUNCTION u3(VAR r: reference): 0..255↲
FUNCTION u4(VAR r: reference): 0..255↲
↲
If one of these functions is called with a parameter with ↓
value NIL a fault occurs. Otherwise the result is the ↓
indicated u-attribute of the designated buffer.↲
↲
The size of a buffer may be read using the predefined ↓
function bufsize:↲
↲
FUNCTION bufsize(VAR r: reference): 0..maxint↲
If bufsize is called with a parameter with value NIL a fault ↓
occurs. Otherwise the size of the designated buffer is ↓
returned as result.↲
↲
The following six predefined routines may be used to read ↓
and set the values of the attributes offset, top and byte ↓
count.↲
↲
FUNCTION offset(VAR r: reference): 0..maxint↲
FUNCTION top(VAR r: reference): 0..maxint↲
FUNCTION bytecount(VAR r: reference): 0..maxint↲
↲
If one of these three functions is called with a parameter ↓
with value NIL a fault occurs. Otherwise the result is the ↓
value of the indicated attribute of the designated buffer.↲
↲
PROCEDURE setooset(VAR r: reference; val: 0..maxint)↲
PROCEDURE settop(VAR r: reference; val. 0..maxint)↲
PROCEDURE setbytecount(VAR r: reference; val. 0..maxint)↲
↲
If one of these three functions is called with a reference ↓
parameter with value NIL a fault occurs. Otherwise the value ↓
of the val parameter is assigned to that attribute of the ↓
designated buffer which is indicated by the procedure name.↲
↲
┆8c┆┆83┆┆c8┆↓
Chain (linked lists) of buffer stacks may be built and ↓
manipulated by means of objects of the types reference and ↓
chain and the predefined routines chaininsert, chainextract, ↓
chainup, chaindown, chainstart, chainreset and described in ↓
section 10.2. A chain object serves as a handle to such a ↓
list. Access to a list cannot be transferred via a mailbox.↲
↲
The routines eventkind, resetevent, u1, u2, u3, u4, setu1, ↓
setu2, setu3, setu4, bufsize, offset, top, bytecount, ↓
setoffset, settop, and setbytecount may also be called with ↓
a parameter of type chain instead of reference. In this ↓
case the relevant attribute of the current buffer is ↓
accessed. The chain must not be empty; if so a fault occurs.↲
↲
↲
┆b0┆┆a1┆3.9 Structured Types↲
↲
An object of a structured type is a structured collection of ↓
subobjects of other (simpler) types. The value of such an ↓
object is a structured collection of values of the sub-↓
objects. Structures may be arbitrarily deep, i.e. sub-↓
objects of a structured object may themselves be of ↓
structured types. The typesof the subobjects of objects of a ↓
structurted type are called the ┆a1┆constituent types┆e1┆. Sub-↓
objects which are not of structured types are called ↓
┆a1┆components┆e1┆. The total set of components of a structured ↓
object are: those sub-objects which are themselves ↓
components plus the components of the remaining sub-objects.↲
↲
If any component type of a structured type is protected ↓
(pointer or shielded) the structured tye is also said to be ↓
protected.↲
↲
The comparison operators = and <> may be applied to pairs of ↓
operands of the same structured type, provided they apply to ↓
all components. The result produced by the = operator is ↓
true if all component values are pairwise equal, otherwise ↓
false. The result prodcued by <> is just the opposite, i.e. ↓
true if any pair of component values are not equal.↲
↲
┆8c┆┆83┆┆e0┆↓
A structure type is an array type or a record type, ↓
depending on the way it is built.↲
↲
↲
↲
↲
↲
If the keyword PACKED is present the defined type is called ↓
a packed type. objects of the type are also called packed. ↓
Packed types constitute a sub-class of the class of ↓
structured types. Packing indicates that the code generated ↓
by a compiler to access objects of the defined type should ↓
be optimized for compactness of object representation rather ↓
than execution time. An important sub-class of packed types ↓
is the descriptive types, cf. section 3.11.↲
↲
A packed object may contain components which either do not ↓
start on a byte boundary or do not occupy a multiple of 8 ↓
bits (or both). Such a component is called an irregular ↓
object. It may not be used for retyping in a with statement ↓
(cf. section 5.8) or as an actual parameter to be ↓
transferred by address (cf. section 6.2).↲
↲
Array and record types are described in the following two ↓
subsections.↲
↲
┆a1┆Note:↲
Unless a packed type is descriptive, cf. section 3.11, the ↓
precise effect of packing is not defined. In particular, if ↓
the type has constituent types which are not static, packing ↓
cannot be expected to have any effect.↲
↲
↲
┆b0┆┆a1┆3.9.1 Array Types↲
↲
The sub-objects of an array are called elements. The ↓
elements are organized by indexing.↲
↲
↲
↲
↲
┆8c┆┆83┆┆ec┆↓
The type specified between the parantheses is called the ↓
index type. It must be an ordinal type. All elements of an ↓
object of the defined array type are of the type specified ↓
following OF, called the element type. Every object of the ↓
array type has precisely one element associated with each ↓
value of the index type.↲
↲
The syntax ARRAY(t┆82┆1┆81┆, t┆82┆2┆81┆, ..., t┆82┆n┆81┆) OF element_type↲
is permissible as shorthand for↲
ARRAY(t┆82┆1┆81┆) OF ARRAY(t┆82┆2┆81┆) OF ... ARRAY(t┆82┆n┆81┆) OF element_type.↲
Similarly PACKED ARRAY(T┆82┆1┆81┆, t┆82┆2┆81┆, ..., t┆82┆n┆81┆) OF element_type↲
is legal shorthand for PACKED ARRAY(t┆82┆1┆81┆) OF PACKED ARRAY(t┆82┆2┆81┆) ↓
OF ... PACKED ARRAY(t┆82┆n┆81┆) OF element type.↲
↲
The elements of an array object are accessed by indexing.↲
↲
↲
↲
↲
The type of the denoted object must be an array type. The ↓
index expression must be assignable to the index type of ↓
this type. It is evaluated when access is made to the ↓
indexed element. the indexed element is that element of the ↓
array object whichis associated with the value of the ↓
expression. The type of the indexed element is the element ↓
type of the array type.↲
↲
The syntax a(i┆82┆1┆81┆, i┆82┆2┆81┆, ..., i┆82┆n┆81┆), where a denotes an array ↓
object, is permissible as shorthand for a(i┆82┆1)(i┆82┆2) ... (i┆82┆n┆81┆).↲
↲
┆a1┆Note:↲
The above description implies that in general a range check ↓
is performed when an array element is accessed by indexing. ↓
A compiler may optionally allow index checking to be ↓
suppressed.↲
↲

════════════════════════════════════════════════════════════════════════
↓
┆a1┆Example┆e1┆: (cf. section 3.3)↲
VAR↲
  amatrix: matrix_10;↲
  temp_column: column(10);↲
  ...↲
  temp_column:=amatrix(i); -- assignment of complete column↲
  amatrix(i,j):=amatrix(j,i); -- single component↲
  ...↲
↲
↲
┆b0┆┆a1┆3.9.2 Record Types↲
↲
The sub-objects of a record are called fields. The fields ↓
are organized by naming.↲
↲
↲
↲
↲
↲
↲
↲
All the field names in a record type definition must be ↓
dcistinct. Each field name introduces and identifies a ↓
field. The type of the field, called the field type, is ↓
specified by the common type specification following :. A ↓
field type may not be specified by an 'enumeration-type ↓
definition'.↲
↲
The fields of a record are accessed by selection by name.↲
↲
↲
↲
↲
The tye of the denoted object must be a record type. The ↓
field name must occur in the definitionof the record type. ↓
The selected field is that field of the record object which ↓
is identified by the field name. Its type is the specified ↓
field type.↲
↲
┆8c┆┆83┆┆d4┆↓
An abbreviated syntax for field access may be used in with ↓
statements, cf. section 5.8.↲
↲
┆a1┆Example:↲
VAR↲
  rec: RECORD↲
    f1,f2: integer;↲
╞	f3: boolean↲
  END(*RECORD*);↲
  ...↲
  rec.f1:=rec.f1+rec.f2↲
  or↲
  WITH rec DO f1:=f1+f2↲
↲
↲
┆b0┆┆a1┆3.9.3 Notation for Values of Structured Types↲
↲
Values of a structured type may be denoted by lists of ↓
element or field values.↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
The 'bound-type_name' or 'parameterized type binding' ↓
specifies the type of the structured value, which must be a ↓
structured type. The construct between (: and :) is ↓
evaluated to a list of values, by evaluating the expressions ↓
in the order of occurrence. If the type is specified by a ↓
'parameterized tye binding' it is established before the ↓
value list is evaluated.↲
↲
┆8c┆┆83┆┆c8┆↓
If the structured type is an array type the values in the ↓
list are the element values in index order. The number of ↓
values must equal the number of elements and the type of ↓
each value must be assignable to the element type; otherwise ↓
a fault occurs. a 'repeated value', if present, is ↓
equivalent to a number ofrepeated occurrences of its ↓
'value_expression'; however, the expression is only ↓
evaluated once. the number is given by the ordinal value ↓
corresponding to the value of the 'repetition_expression' ↓
which must be a non-negative integer. if the number is ↓
negative a fault occurs.↲
↲
If the structured type is a record type the values in ↓
thelist are the field values in the order in which the field ↓
names occur in the definition of the record type. The number ↓
of values must equal the number of fields and the type of ↓
each value must be assignable to the corresponding field ↓
type; otherwise a fault occurs. If the record type contains ↓
unused fields (cf. section 3.11) no value should be given ↓
for these. They are implicitly set to value zero. In the ↓
case of a record type a 'repeated value' must not occur.↲
↲
The type specification may be omitted when the type it ↓
specifies can be inferred from the context, i.e. in the ↓
following two situations:↲
↲
1. ┆84┆The 'structured value' occurs as a 'value_expression' ↓
┆19┆┆83┆┄┄within a larger 'structured value'↲
↲
2. ┆84┆The 'structured value' occurs as an ↓
┆19┆┆83┆┄┄'initialization_expression' in a variable declaration.↲
↲
┆a1┆Example┆e1┆: (cf. section 3.3)↲
CONST↲
  identify_3=matrix_3(:(:1,0,0:), (:0,1,1:), (:0,0,1:):);↲
  nul_list= list(:length***0:);↲
VAR↲
  a4: matrix(4):= (:4***(:4***0:):); -- initially null↲
↲
↲
┆8c┆┆83┆┆e0┆↓
┆b0┆┆a1┆3.9.4 String Types↲
↲
The family of one-dimensional character string (array) types ↓
is predefined:↲
↲
string(length: 0..255)= ARRAY(1..length) OF char↲
↲
Values of types from the string family may be denoted by ↓
character strings. A character stringis a string of graphic ↓
symbols, each representing a character value, enclosed in ↓
double quotes. The double quote character may itself be part ↓
of a character string. In this case it must be indicated by ↓
two adjacent occurrences of the " graphic symbol. Individual ↓
non-graphic characters may be included in a character string ↓
by means of the concatenation operator &.↲
↲
The specific type of a character string, i.e. the particular ↓
member of the string family of which it denotes a value, is ↓
determined by its length, i.e. the number of characters it ↓
consists of.↲
↲
As an implementation feature character strings may be ↓
truncated or extended with NUL characters when appropriate ↓
in the context, e.g. when occurringon the right hand side of ↓
an assignment statement where the corresponding component on ↓
the left hand side is of a string type with different ↓
length.↲
↲
┆a1┆Examples:↲
"this is a string"↲
"x""x" (* a string of length 3 *)↲
"*** illegal input message" & BEL & CR & LF -- string(28)↲
↲
↲
┆b0┆┆a1┆3.10 Type Compatibility↲
↲
The compatibility relations defined in this section are used ↓
to determine when a value may be assigned to an object, ↓
┆8c┆┆83┆┆c8┆↓
either explicitly when an assignment statement is executed ↓
or implicitly in connection with parameter passing.↲
↲
The essential relation is ┆a1┆assignment compatibility┆e1┆. However, ↓
the basis for that relation is the compatibility relation ↓
between types which is therefore defined first. The ↓
compatibility relation applies to established types.↲
↲
Two types are said to be the same if:↲
- both are the same predefined type, or↲
- both are specified as the same bound-type_name, or↲
- ┆84┆both are specified as a binding of the same parameterized-↓
┆19┆┆82┆┄┄type_name and the values of the actual type parameters are ↓
┆19┆┆82┆┄┄pairwise equal.↲
↲
Two objects are said to be of the same type if their types ↓
are the same (cf. above), if they are variables introduced ↓
in the same list of variable names, cf. subsection 3.12.2, ↓
or if they are formal parameters of kind value introduced in ↓
the same formal name list, cf. section 6.1.↲
↲
Two types are said to be compatible if:↲
- they are the same type (cf. above), or↲
- ┆84┆one is a subrange of the other (or both are subranges of ↓
┆19┆┆82┆┄┄the same type), or↲
- both are set types and the base types are compatible, or↲
- both are specified as `tname, where tname is a type name.↲
↲
Type computation rules are defined for expressions (cf. ↓
chapter 4) so as to associate every expression with a type, ↓
either an explicitly specified type, or a predefined type ↓
determined implicitly by the structure of the expression. An ↓
expression exp of type t┆82┆2┆81┆ is defined to be assigment ↓
comptable with the type t┆82┆1┆81┆ if:↲
↲
- ┆84┆t┆82┆1┆81┆ and t┆82┆2┆81┆ are compatible ordinal types and the value of ↓
┆19┆┆82┆┄┄exp is within the range specified for t┆82┆1┆81┆, if any, or↲
┆8c┆┆83┆┆bc┆↓
- ┆84┆t┆82┆1┆81┆ and t┆82┆2┆81┆ are compatible set types and all members of the ↓
┆19┆┆82┆┄┄value of exp are within the range specified for t┆82┆1┆81┆, or↲
- ┆84┆t┆82┆1┆81┆ and t┆82┆2┆81┆ are compatible machine pointer, shielded, or ↓
┆19┆┆82┆┄┄structured types, or↲
- t┆82┆1┆81┆ and t┆82┆2┆81┆ are both string types, cf. subsection 3.9.4.↲
↲
Throughout this manual the shorthand form "assignable to" ↓
may be used instead of "assignment compatible with".↲
↲
┆a1┆Example:↲
In each line below the types of a and b are compatible.↲
a: boolean;╞	╞	b: boolean;↲
a: def_type;╞	╞	b: def_type;↲
a: param_type(7);╞	b: param_type(7);↲
a: 1..10;╞	╞	b: 2..15;↲
a: SET OF 1..10;╞	b: SET OF 2..15;↲
a: `ptrtype;╞	╞	b: `ptrtype;↲
↲
↲
┆b0┆┆a1┆3.11 Object Layout↲
↲
In general the definition of the language does not prescribe ↓
any specific layout for objects, and thus the way objects ↓
are laid out in memory and the way their values are ↓
represented depend on the implementation in question. In ↓
order to allow cooperation with processes whose programs are ↓
not written in Real-Time Pascal these aspects of an ↓
implementation must always be documented carefully.↲
↲
By specifying a ┆a1┆descriptive type┆e1┆, however, it is possible ↓
within certain limits for the programmer to explicitly ↓
determine the layout of objects. Descriptive types ↓
constitute a subclass of packed types, recursively defined ↓
as having constituent types which are all either machine or ↓
static ordinal types, or themselves descriptive.↲
↲
This definition implies that all component types of a ↓
descriptive tye are ordinal or machine types. Components of ↓
┆8c┆┆83┆┆c8┆↓
machine types are laid out as machine bytes or words (cf. ↓
section 3.5), and the representation of ordinal type ↓
components is presently described. Notice that the ↓
description only covers sub-objects of objects of ↓
descriptive types.↲
↲
A component of an ordinal type is represented as a binary ↓
number in a maximum of 16 bits. If the type includes ↓
negative values the two's complement representation is used. ↓
The number of bits used to represent objects of some type ↓
depends on the range of values. Let minval and maxval be the ↓
ordinal values corresponding to the first and last value of ↓
the type, respectively. Then the number of bits used for ↓
objects of the type is:↲
↲
minval<0, maxval<0: log┆82┆2┆81┆(-minval)+1↲
minval<0, maxval>0: max  log┆82┆2┆81┆(-minval), log┆82┆2┆81┆(maxval+1)  +1↲
minval>0, maxval>0: log┆82┆2┆81┆(maxval+1)↲
↲
The numbers obtained by these formulae must be rounded up to ↓
obtain integral numbers.↲
↲
As sub-objects of an object of a descriptive type need not ↓
occupy whole bytes the total object is considerd as a ↓
bitstring rather than as a bytestring. The orderingof bits ↓
within such a bitstring is defined as follows:↲
↲
- bits within separate bytes are ordered by byte address,↲
- ┆84┆bits within the same byte are ordered by significance, ↓
┆19┆┆82┆┄┄i.e. least significant bits first.↲
↲
This implies that the whole bitstring will be ordered by ↓
significance, see Fig. 2.↲
↲

════════════════════════════════════════════════════════════════════════
↓
               bit number↲
           ┆a1┆ 0 1 2 3 4 5 6 7 ↲
         0 ┆a1┆!               !┆e1┆   When viewed in this fashion,↲
relative 1 ┆a1┆!               !┆e1┆   i.e. the significance of bit↲
  byte   . ┆a1┆!               !┆e1┆   i is the ith power of 2, bits↲
 address . ┆a1┆!               !┆e1┆   are ordered as the characters↲
         n ┆b0┆┆f0┆┆a1┆!               !┆e1┆   on a text page.↲
↲
Figure 2: Bitstring ordering.↲
↲
An ordering is also defined for the sub-objects of an object ↓
of a structured type: in the sace of an array type by index; ↓
in the case of a record type by the order of the field names ↓
in the record type definition.↲
↲
The following simple rule defines the layout of objects of a ↓
descriptive type: within the bitstring occupied by the ↓
object subobjects are located contiguously and in order. ↓
Notice that this rule, like the definition of a descriptive ↓
type, is recursive. The following points complete the rule:↲
↲
- ┆84┆every definition of a descriptive type is implicitly ↓
┆19┆┆82┆┄┄extended with an unused component and the end so that ↓
┆19┆┆82┆┄┄objects of the type occupy an integral number of bytes, if ↓
┆19┆┆82┆┄┄this property is not already satisfied by the type as ↓
┆19┆┆82┆┄┄stated,↲
- ┆84┆no component may cross two byte boundaries. When possible, ↓
┆19┆┆82┆┄┄an unused component is inserted to fill up a byte so that ↓
┆19┆┆82┆┄┄this situation is avoided.↲
↲
An unused field of a descriptive record type may be ↓
specified explicitly in order to adjust the positioning of ↓
subsequent fields.↲
↲
↲
↲
↲
┆8c┆┆83┆┆bc┆↓
An unused-specificationis equivalent to the declaration of a ↓
field of the specified type which must be a static ordinal ↓
type. The field is not accessible, i.e. it cannot be ↓
selected. Assignment to an unused field can only be made by ↓
assigning a value to the record object as a whole.↲
↲
┆a1┆Note:↲
If the comparison operator = and <> are applied to objects ↓
of structured types with unused components they are also ↓
applied to unused fields.↲
↲
┆a1┆Example:↲
Consider the types↲
  rec_type= RECORD↲
    a: integer;↲
    b: 0..255;↲
    c: 0..7;↲
    d: -3..4;↲
    e: -1000..1000;↲
    f: char;↲
    g: boolean;↲
    h: integer↲
  END(*RECORD:)↲
↲
  arr_type =ARRAY(1..4) OF 0..2000 (* 11 bits *)↲
↲
Typical layouts for objects of these types are shown to the ↓
left in the figure below; note that this representation is ↓
not specified by the language. However, if the keyword ↓
PACKED had been present before RECORD/ARRAY, the types would ↓
have been descriptive and their layout prescribed to be as ↓
shown to the right.↲
↲

════════════════════════════════════════════════════════════════════════
↓
rec_type:↲
          ┆a1┆ 0 1 2 3 4 5 6 7 ┆e1┆          ┆a1┆ 0 1 2 3 4 5 6 7 ↲
        0 ┆a1┆!┆e1┆               ┆a1┆!┆e1┆        0 ┆a1┆!┆e1┆               ┆a1┆!↲
        1 ┆a1┆!       a       !┆e1┆        1 ┆b0┆┆f0┆┆a1┆!       a       !↲
        2 ┆a1┆!       b       !┆e1┆        2 ┆a1┆!       b       !↲
        3 ┆a1┆!       c       !┆e1┆        3 ┆a1┆!  c  !   d   !?!↲
        4 ┆a1┆!       d       !┆e1┆        4 ┆a1┆!     e-10      !↲
        5 ┆a1┆!┆e1┆               ┆a1┆!┆e1┆        5 ┆a1┆! e-hi!  f-10   !↲
        6 ┆a1┆!       e       !┆e1┆        6 ┆a1┆! f-hi!g!   ?   !↲
        7 ┆a1┆!       f       !┆e1┆        7 ┆a1┆!┆e1┆               ┆a1┆!↲
        8 ┆a1┆!       g       !┆e1┆        8 ┆a1┆!      h        !↲
        9 ┆b0┆┆f0┆┆a1┆!┆e1┆               ┆a1┆!↲
       10 ┆a1┆!       h       !↲
↲
arr_type:↲
          ┆a1┆ 0 1 2 3 4 5 6 7 ┆e1┆          ┆a1┆ 0 1 2 3 4 5 6 7 ↲
        0 ┆a1┆!┆e1┆               ┆a1┆!┆e1┆        0 ┆a1┆┆e1┆!   (1┆a1┆)         !↲
        1 ┆a1┆!     (1)       !┆e1┆        1 ┆a1┆!     !┆e1┆     ┆a1┆    !↲
        2 ┆a1┆!┆e1┆               ┆a1┆!┆e1┆        2 ┆a1┆!       (2) !  ?!↲
        3 ┆a1┆!     (2)       !┆e1┆        3 !   (3┆a1┆)         !↲
        4 ┆a1┆!┆e1┆               ┆a1┆!┆e1┆        4 ┆a1┆!     !┆e1┆ (4) ┆a1┆    !↲
        5 ┆a1┆!     (3)       !┆e1┆        5 ┆a1┆!           !  ?!↲
        6 ┆a1┆!┆e1┆               ┆a1┆!↲
        7 ┆a1┆!     (4)       !↲
↲
Figure 3: Example of object layout.↲
↲
↲
┆b0┆┆a1┆3.12 Object Declarations↲
↲
Declarations of objects may occur in the declaration part of ↓
a program or routine block, cf. chapter 6.↲
↲
An object declaration inctroduces and names an object which ↓
may be used in the remainder of the block.↲
↲
↲

════════════════════════════════════════════════════════════════════════
↓
┆b0┆┆a1┆3.12.1 Constant Declarations↲
↲
A constant declaration serves to name a constant object, ↓
i.e. an object whose value can be computed at compile-time ↓
and which cannot be altered dynamically by assignment.↲
↲
↲
↲
↲
↲
Each constant name introduced in a constant declaration ↓
denotes a constant object the type and value of which is ↓
determined by the expression following =. The expression ↓
must be a constant expression as described in chapter 4. The ↓
type of a constant must not be protected.↲
↲
↲
┆a1┆3.12.2 Variable Declarations↲
↲
A variable or shared declaration serves to name one or more ↓
stack-allocated private or shared variables and optionally ↓
to specify initial values for instances of such variables.↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
The variables introduced in a 'variable declaration' are ↓
private variables, i.e. they can only be accessed by the ↓
┆8c┆┆83┆┆e0┆↓
process in whose stack they are allocated. The variables ↓
introduced in a 'shared declaration' are shared variables ↓
which can only be accessed in region statements.↲
↲
The type of each variable named in a variable or shared ↓
declaration is given by the first following type ↓
specification and the initial value by the expression ↓
following :=, if present. The type of the expression must be ↓
assignable to the specified type of the variable. When ↓
several variable names are listed, separated by commas, each ↓
name introduces a variable of the specified type. The type ↓
of a shared variable must not be process, reference, or ↓
chain; nor may these types occur as component types in the ↓
types of shared variables.↲
↲
When a variable or shared declaration is elaborated the ↓
specified types are established; memory is allocated on the ↓
stack for an instance of each of the named variables; the ↓
initialization expressions, if present, are evaluated; and ↓
the values of the expressions become initial values of the ↓
variables. An initialization expression must not contain ↓
function calls. However, the predefined functions abs, byt, ↓
chr, int, ord, pred, succ, and wrd may be used.↲
↲
Variables of components for which initial values or states ↓
are predefined are initialized accordingly. The initial ↓
value of a variable for which an initial value is neither ↓
predefined nor specified is undefined.↲
↲
In a structured value occurring in an initialization ↓
expression the notation ? may be used for components of ↓
protected types. This makes it possible to combine the ↓
predefined initialization of these components with an ↓
explicitly specified initialization of the remaining ↓
components.↲
↲
A varsize call is similar in form to a function call. It ↓
allows the size of a variable to be used in computations.↲
↲
↲
↲
↲
┆8c┆┆83┆┆f8┆↓
The 'variable_name' must be the name of a variable. It must ↓
have been introduced in a variable declaration. The value of ↓
a varsize call is the size (number of bytes) of the variable ↓
as computed whenits type was established. The type of a ↓
varsize call is integer.↲
↲
↲
┆a1┆┆b0┆3.13 Notation for Objects and Values↲
↲
An object which is declared or part of a (larger) declared ↓
object or accessed through a declared pointer, may be ↓
referred to by denotation.↲
↲
↲
↲
↲
↲
↲
↲
The denoted object is said to be ┆a1┆accessed┆e1┆ when: an ↓
assignment statement in which it appears on the left hand ↓
side is executed; or the factor which it constitutes in some ↓
expression is evaluated.↲
↲
If the 'object denotation' is an 'object_name' its type is ↓
the type of the named object as determined by its ↓
declaration. The types of the other forms of denoted objects ↓
are described in previous sections of this chapter.↲
↲
The targetof an assignment may either be a variable object ↓
or the implicit result object associated with a function ↓
call.↲
↲
↲
↲
↲
↲
┆8c┆┆83┆┆bc┆↓
When an object denotation occurs as a variable denotationit ↓
must denote an object which is a variable or part of a ↓
variable in the stack or heap of a process, or superimposed ↓
on a buffer in a lock statement. It must not be a constant ↓
or part of a constant.↲
↲
When a function name occurs as a variable denotation it ↓
denotes the implicitly declared result object of an ↓
activation of the function it names. A function name may be ↓
used in this fashion only in the action part of the ↓
function, i.e. not in inner blocks.↲
↲
The type of a variable denotationis the type of the denoted ↓
object or the result type of the function, whichever ↓
applies.↲
↲
Values which are not the values of objects or sub-objects ↓
may be used in expressions.↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
A value denotation denotes the value of an anonymous object, ↓
the type and value of which is as described for the relevant ↓
one of the possible forms.↲
↲

════════════════════════════════════════════════════════════════════════
↓

════════════════════════════════════════════════════════════════════════
↓
┆14┆┆b3┆┆06┆┆0b┆↲
┆a1┆┆b0┆4. EXPRESSIONS↲
↲
An expression describes either an object to be addressed or ↓
some computation to be performed by applying operators and ↓
functions, predefined as well as programmer-defined, to ↓
values of objects as they are at the time of computation and ↓
to constant values which may be denoted directly in the ↓
expression.↲
↲
The operators of the language are divided in groups with ↓
different precedence. In order of increasing precedence the ↓
groups are: relational operators, addition-type operators, ↓
multiplication-type operators, and the negation operator.↲
↲
All operators are described in chapter 3 in conjunction with ↓
the description of the types of the operands they apply to. ↓
Some operators exist in several semantically distinct ↓
versions, applicable to different types of operands and ↓
producing results in different ways depending on the operand ↓
types, e.g. <= may be used for integer (or in general: ↓
ordinal value) comparison, as well as for set comparison ↓
(inclusion).↲
↲
In section 4.1 reference is given, for each opeator, to all ↓
sections where a version of that operator is described. The ↓
following selection rule is used in the application of ↓
operators occurring in expressions: If the types of the ↓
operand(s) provided for an operator correspond to one of the ↓
versions of that operator, then that version of the operator ↓
is selected. Otherwise the expression is illegal. The type ↓
of the result is determined according to the description of ↓
the selected version of the operator. The result may again ↓
be used as an operand of another operator and the selection ↓
rule may then be applied repeatedly.↲
↲
An expression which is used as an actual parameer where the ↓
kind of the corresponding formal parameter is variable, ↓
shared or inspect (cf. chapter 6) must have the form of an ↓
┆8c┆┆83┆┆c8┆↓
'object denotation'. Such an expressionis called an ┆a1┆object ↓
┆19┆┄┄┆84┆expression┆e1┆. The evaluation of an object expression stops ↓
when the address of the denoted object has been computed. In ↓
all other cases the evaluation of an expression proceeds ↓
until a value has been obtained, as described in the ↓
following section.↲
↲
↲
┆b0┆┆a1┆4.1 Evaluation of Expressions↲
↲
The evaluation of an expression yields a type and a value. ↓
This section describes how the tye and value are obtained ↓
from the types and values of the parts of the expression ↓
which constitute the operands at the various stages of ↓
computation.↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
The expression is evaluated by evaluating the simple ↓
expression(s) in the order of occurrence. Then, if no ↓
operator is present, the type and value of the expression ↓
are the type and value of the (only) simple expression. ↓
Otherwise the appropriate version of the operator is applied ↓
to the values of the simple expressions; the result is the ↓
value of the expression, its type being boolean for all ↓
relational operators.↲
↲
↲
↲
↲
↲
↲
↲
┆8c┆┆84┆┆a8┆↓
A leading + or - implies an implicit left term with type ↓
integer and value 0.↲
↲
┆06┆versions (section)↲
↲
↲
↲
↲
↲
↲
↲
↲
The evaluation of a simple expression proceeds from left to ↓
right. The leftmost term (possibly an implicit 0) is ↓
evaluated, yielding a ┆a1┆preliminary result┆e1┆. The following is ↓
then performed repeatedly:↲
↲
The preliminary result is used as left operand of the ↓
leftmost remaining operator. The leftmost remaining term is ↓
evaluated and used as right operand. The appropriate version ↓
of the operator is then applied and produces a new ↓
preliminary result.↲
↲
When no more operators and terms are left the simple ↓
expression has been completely evaluated; the final type and ↓
value of the preliminary result constitute the type and ↓
value of the simple expression.↲
↲
There is one exception to the rule described above: if the ↓
left operand of the OR-operator is of type boolean and has ↓
value true, then the evaluation of the right operand is ↓
omitted; however, its type must still be boolean.↲
↲
↲
↲
↲
↲
↲
┆8c┆┆83┆┆c8┆↓
┆06┆version (section)↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
The evaluation of a term proceeds from left to right in the ↓
same fashion as for a simple expression (i.e. substitute ↓
'factor' for 'term' and 'term' for 'simple expression' in ↓
the above description).↲
↲
There is one exception to the general rule: if the left ↓
operand of the AND-operator is of type boolean and has value ↓
false, then the evaluation of the right operand is omitted; ↓
however, its type must still be boolean.↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
The type and value of a factor are obtained as described ↓
below for each of the possible forms:↲
↲
object denotation:↲
The value of the factor is the value of the denoted object ↓
at the time of evaluation. The type of the factor is the ↓
┆8c┆┆83┆┆c8┆↓
type of the denoted object, except if this type is a ↓
subrange in which case the type of the factor is the base ↓
type of the subrange. If the value of the object is ↓
undefined (not initialized) the effect of evaluating the ↓
factor is not defined.↲
↲
value denotation:↲
The type and value of the factor are the type and value of ↓
the denoted value, cf. section 3.13.↲
↲
function call:╞	4.2↲
typesize call:╞	3.2↲
varsize call:╞	╞	3.12.2↲
link call:╞	╞	9.1↲
unlink call:╞	╞	9.1↲
create call:╞	╞	9.1↲
↲
The type and value of the factor are the type and value of ↓
the call, as described in the indicated section.↲
↲
(expression):↲
The factor is evaluated by evaluating the expression. The ↓
tye and value of the factor are the type and value of the ↓
expression.↲
↲
NOT neg_factor:↲
the type and value of the factor are obtained by evaluating ↓
the neg_factor and applying the appropriate version of the ↓
NOT-operator to the result. The versions of the NOT-operator ↓
are described in subsection 3.4.1 and section 3.5.↲
↲
┆a1┆Note:↲
The precedence rules of Real-Time Pascal are those of ↓
standard Pascal which differ from the rules of other ↓
programming languages (e.g. ALGOL and PL/M languages).↲
↲

════════════════════════════════════════════════════════════════════════
↓
┆a1┆Example:↲
As a consequence of the precedence rules the following is ↓
not a legal expression:↲
 ╞	0<x AND x<10↲
The expression should be written as:↲
╞	(0<x) AND (x<10)↲
↲
↲
┆b0┆┆a1┆4.2 Function Call↲
↲
A function call causes a value to be computed by an ↓
activation of the indicated function.↲
↲
↲
↲
↲
↲
The function name must be the name of a function, either ↓
predefined or programmer-defined. Evaluation of a function ↓
call takes place in two steps:↲
↲
1. ┆84┆The actual parameters are evaluated in the order of ↓
┆19┆┆83┆┄┄occurrence.↲
2. ┆84┆An activation of the block associated with the function ↓
┆19┆┆83┆┄┄name is created and executed, cf. chapter 6.↲
↲
The type of the function call is the result type of the ↓
function. The value of the function call is the value of the ↓
implicit result object associated with the activation of the ↓
function block when the execution of its action part ↓
terminates. If the value is undefined (no assignment) the ↓
effect of evaluating the function call is not defined.↲
↲
↲
┆b0┆┆a1┆4.3 Constant Expressions↲
↲
Constant expressions can be evaluated at compile-time. Only ↓
constant expressions may be used in constant declarations. ↓
If all expressions used in a type definition are constant ↓
expressions the type is said to be static.↲
↲
┆8c┆┆83┆┆ec┆↓
Constant expressions are recursively defined by the ↓
following restrictions.↲
↲
1. All denoted objects must be constants.↲
2. ┆84┆Only the following (predefined) functions may be called: ↓
┆19┆┆83┆┄┄abs, chr, int, ord, pred, succ, wrd, and byt.↲
3. Any typesize call must name a static type.↲
4. ┆84┆'link call', 'unlink call', and 'create call' must not ↓
┆19┆┆83┆┄┄occur.↲
5. Factors of set types must not occur.↲

════════════════════════════════════════════════════════════════════════
↓
┆b0┆┆a1┆5. STATEMENTS↲
↲
This chapter contains subsections describing the syntax and ↓
the use of the different statements which are included in ↓
the Real Time Pascal language. Most of the statements are ↓
also found in standard Pascal and are well known language ↓
elements.↲
↲
↲
┆b0┆┆a1┆5.1 Compound Statement↲
↲
The statements of a program describe the actions which are ↓
executed by an incarnation. These statements are collected ↓
in a compound statement.↲
↲
↲
↲
↲
↲
The statements are executed one at a time in the specified ↓
order. When all have been executed the compound statement ↓
has been completely executed or ┆a1┆exhausted┆e1┆.↲
↲
Below, all statement forms are given together with reference ↓
to their precise decription:↲
↲
┆06┆section↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
┆8c┆┆84┆┆c0┆↓
┆a1┆Note:↲
State ment may be empty.↲
↲
↲
┆b0┆┆a1┆5.2 Data Transfer Statements↲
↲
Assignment and exchange statements are the basic building ↓
blocks for other types of statements. They serve to transfer ↓
values to objects.↲
↲
↲
┆b0┆┆a1┆5.2.1 Assignment Statement↲
↲
The execution of an assignment statement causes the current ↓
value of a variable to be replaced with a new value ↓
specified by an expression. The right hand side expression ↓
must be of a type which is assignment compatible (cf. ↓
section 3.10) with the type of the variable.↲
↲
↲
↲
↲
The execution of an assignment statement takes place in four ↓
steps:↲
↲
1) ┆84┆The variable denotation is evaluated as an object ↓
┆19┆┆83┆┄┄expression.↲
↲
2) The right hand side expression is evaluated.↲
↲
3) ┆84┆the run-time part of the type checking, including tests ↓
┆19┆┆83┆┄┄for range constraints, is performed. A fault occurs if ↓
┆19┆┆83┆┄┄some constraint is violated.↲
↲
4) ┆84┆The value of the expression replaces the value of the ↓
┆19┆┆83┆┄┄variable.↲
↲
┆8c┆┆83┆┆bc┆↓
Assignments cannot be made to variables of shielded types or ↓
of structured types with shielded component types.↲
↲
┆a1┆Examples:↲
current_index:=current_index+1↲
catalog(current_index).author:="Andersen H C"↲
matrix:= matrix_type(:(:1, 0, 0:).↲
╞	╞	       (:0, 1, 0:),↲
╞	╞	       (:0, 0, 1:):)↲
↲
↲
┆a1┆┆b0┆5.2.2 Exchange Statement↲
↲
The values of two variables may be exchanged by executing an ↓
exchange statement.↲
↲
↲
↲
↲
The denoted objects must be variables, and they must be of ↓
the same type, cf. section 3.10. This type, or any of its ↓
components types, must not be mailbox, pool, chain, or port.↲
↲
The execution of an exchange statement takes place in two ↓
steps:↲
↲
1) ┆84┆The addresses of the left hand side and right hand side ↓
┆19┆┆83┆┄┄variables are evaluated, in that order.↲
↲
2) ┆84┆The values of the objects located at the addresses ↓
┆19┆┆83┆┄┄evaluated in step 1 are interchanged.↲
↲
If the two variables are of type reference or process or if ↓
they have components of these types the interchange takes ↓
place as an indivisible operation so that the integrity of ↓
references to buffers and processes is preserved.↲
↲

════════════════════════════════════════════════════════════════════════
↓
┆a1┆Examples:↲
current_buffer_ref:=:temp_buffer↲
matrix(i):=:matrix(j)↲
↲
↲
┆b0┆┆a1┆5.3 If Statement↲
↲
An if statement selects for execution one of two (possibly ↓
empty) statements depending on the value of a condition. The ↓
expression specifying the condition must be of the ↓
predefined type boolean.↲
↲
↲
↲
↲
↲
The execution of an if statement takes place in two steps:↲
↲
1) The value of the boolean_expression is evaluated.↲
↲
2) ┆84┆If the expression evaluates to true the statement ↓
┆19┆┆83┆┄┄following THEN is executed. Otherwise the statement after ↓
┆19┆┆83┆┄┄ELSE (if present) is executed.↲
↲
The ambiguous statement:↲
╞	╞	IF e1 THEN IF e2 THEN s1 ELSE s2↲
is defined to be equivalent to:↲
╞	╞	IF e1 THEN BEGIN↲
╞	╞	  IF e2 THEN s1 ELSE s2↲
╞	╞	END↲
↲
┆a1┆Examples:↲
IF day=Sturday THEN↲
  day:=Sunday↲
ELSE↲
  day:=succ(day)↲
↲
IF test THEN produce_test_record↲
↲
↲
┆8c┆┆83┆┆e0┆↓
┆b0┆┆a1┆5.4 Case Statement↲
↲
A case statement selects for execution one of a number of ↓
alternative statements, depending on the value of an ↓
expression. The expression must be of an ordinal type.↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
A case element is a statement labelled by one or more ↓
constant expressions. These constant expressions, called ↓
case labels, must all be of a type compatible with that of ↓
the selecting expression. Consecutive values may be given as ↓
a range, e.g. first..last. All the case labels of one case ↓
statement must be distinct.↲
↲
The execution of a case statement takes place in three ↓
steps: ↲
↲
1) Evaluation of the selecting expression.↲
↲
2) ┆84┆The case element with the label corresponding to the ↓
┆19┆┆83┆┄┄value of the selecting expression is selected for ↓
┆19┆┆83┆┄┄execution.↲
↲
   ┆84┆The "label" OTHERWISE (keyword) corresponds to all values ↓
┆19┆┆83┆┄┄of the type of the selecting expression which do not ↓
┆8c┆┆83┆┆c8┆↓
┆19┆┆83┆┄┄occur as case labels. A fault occurs if no case element ↓
┆19┆┆83┆┄┄corresponds to the value of the selecting expression.↲
↲
3) Execution of the statement of the selected case element.↲
↲
┆a1┆Note:↲
Upon completion of the selected statement the case statement ↓
is also completed.↲
↲
┆a1┆Example:↲
CASE month OF↲
  January..May:╞	....;↲
  October, December:╞	....↲
OTHERWISE╞	╞	....↲
END (* of case *)↲
↲
↲
┆b0┆┆a1┆5.5 Repetitive Statements↲
↲
A repetitive statement specifies that a statement is to be ↓
executed repeatedly, zero or more times.↲
↲
↲
┆b0┆┆a1┆5.5.1 For Statement↲
↲
A for loop may be used if a statement is to be executed a ↓
fixed number of times and/or elaborates on consecutive ↓
values of an object (iteration).↲
↲
↲
↲
↲
↲
↲
↲
The execution of a for statement takes place in five steps, ↓
where three may be repeated:↲
↲
┆8c┆┆83┆┆c8┆↓
1) ┆84┆The start and stop expressions are evaluated and define ↓
┆19┆┆83┆┄┄an ordinal type, i.e. the expressions must be of the same ↓
┆19┆┆83┆┄┄type, which must be an ordinal type.↲
↲
2) ┆84┆The ┆a1┆controlling variable┆e1┆ is allocated as an implicitly ↓
┆19┆┆83┆┄┄declared variable, local to the for statement. Its name ↓
┆19┆┆83┆┄┄is the 'for_name'. The type of the controlling variable ↓
┆19┆┆83┆┄┄is the type of the start and stop expressions. The ↓
┆19┆┆83┆┄┄initial value of the controlling variable is that of the ↓
┆19┆┆83┆┄┄start expression.↲
↲
3) ┆84┆The termination conditionis tested. That is, if TO is ↓
┆19┆┆83┆┄┄specified, execution of the for statement terminates when ↓
┆19┆┆83┆┄┄the value of the controlling variable is greater than the ↓
┆19┆┆83┆┄┄value of the stop expression; if DOWNTO is specified, ↓
┆19┆┆83┆┄┄when the value of the controlling variable is less than ↓
┆19┆┆83┆┄┄the value of the stop expression.↲
↲
4) ┆84┆The statement following DO is executed with the ↓
┆19┆┆83┆┄┄controlling variable acting as a constant (i.e. it must ↓
┆19┆┆83┆┄┄not appear on the left hand side of an assignment ↓
┆19┆┆83┆┄┄statement, nor may it be passed as a variable parameter ↓
┆19┆┆83┆┄┄of a routine call).↲
↲
5) ┆84┆The value of the controlling variable is updated, except ↓
┆19┆┆83┆┄┄if it has already reached the upper or lower bound of the ↓
┆19┆┆83┆┄┄permissible range in which case execution of the for ↓
┆19┆┆83┆┄┄statement terminates immediately. The iteration can ↓
┆19┆┆83┆┄┄either be with increasing values of the controlling ↓
┆19┆┆83┆┄┄variable or with decreasing values. if TO is specified ↓
┆19┆┆83┆┄┄the ordinal value of the controlling variable is ↓
┆19┆┆83┆┄┄incremented in steps of one (succ). If DOWNTO is ↓
┆19┆┆83┆┄┄specified the iteration is with decreasing values (pred). ↓
┆19┆┆83┆┄┄the execution continues at step 3).↲
↲
┆a1┆Note:↲
The two expressions are evaluated once, before the ↓
repetition. If the terminaltion condition is satisfied ↓
┆8c┆┆83┆┆c8┆↓
before the very first repetition the statement (following ↓
DO) of the for statement is not executed at all.↲
↲
┆a1┆Example:↲
FOR month:=January TO December DO↲
  FOR date:=1 TO number_of_days(month) DO↲
    daily_activity(date,month)↲
↲
↲
┆b0┆┆a1┆5.5.2 Loop Statement↲
↲
The loop statement constitutes an unconditional repetitive ↓
control structure, which may be used to define an "infinite" ↓
main loop of a program, only terminated in case of a fault ↓
or parent enforced process termination.↲
↲
↲
↲
↲
↲
The loop statement specifies repeated execution of the ↓
statement sequence in the stated order. The loop may be left ↓
as the result of the execution of a jump statement (cf. ↓
section 5.7).↲
↲
┆a1┆Example:↲
LOOP↲
  next_b:=read_next_buffer;↲
  prepare_buffer(next_b);↲
  send_buffer(next_b)↲
ENDLOOP↲
↲
↲
┆b0┆┆a1┆5.5.3 While Statement↲
↲
Conditional repetition of a statement where the condition is ↓
checked before each execution may be achieved by means of a ↓
while statement.↲
↲
↲
↲
↲
┆8c┆┆83┆┆f8┆↓
The value of the boolean_expression is evaluated before each ↓
execution of the statement. The test-and-execute sequence ↓
goes on as long as the evaluation yields true, when the ↓
result becomes false, possibly the first time, execution of ↓
the while statement terminates.↲
↲
The while statement:↲
  WHILE exp DO st↲
is equivalent to following combination of loop, if and ↓
exitloop statements:↲
  LOOP IF NOT exp THEN EXITLOOP; st ENDLOOP↲
↲
┆a1┆Example:↲
current_index:=first_index;↲
WHILE table(current_index) <> sought_element DO↲
  currfent_index:=current_index+1↲
↲
↲
┆b0┆┆a1┆5.5.4 Repeat Statement↲
↲
Execution of a sequence of statements until some condition ↓
is satisfied may be achieved by means of a repeat statement.↲
↲
↲
↲
↲
↲
Every time the sequence of statements has been executed, the ↓
value of the boolean expression is evaluated and execution ↓
of the repeat statement terminates when the evaluation ↓
yields true.↲
↲
The repeat statement↲
  REPEAT s1; ..; sn UNTIL exp↲
is equivalent to the following special form of the loop ↓
statement:↲
  LOOP s1; ...; sn; IF exp THEN EXITLOOP ENDLOOP↲
↲
┆8c┆┆83┆┆c8┆↓
┆a1┆Example:↲
REPEAT↲
  wait(main_mailbox, ref);↲
  final_message:=do_process(ref);↲
  return(ref)↲
UNTIL final_message↲
↲
↲
┆b0┆┆a1┆5.6 Procedure Call↲
↲
A procedure call serves to establish a binding between ↓
actual and formal parameters, to allocate locally declared ↓
variables, and to invoke execution of the compound statement ↓
of the procedure block in its proper surroundings. A ↓
procedure call consists of the procedure name followed by a ↓
list of actual parameters. If the procedure is declared ↓
without formal parameters, the call consists of the ↓
procedure name only.↲
↲
↲
↲
↲
↲
The execution of a procedure call takes place in two steps:↲
↲
1) ┆84┆The actual parameters are evaluated in the order of ↓
┆19┆┆83┆┄┄occurrence.↲
↲
2) ┆84┆An activation of the block associated with the procedure ↓
┆19┆┆83┆┄┄name is created, including parameter passing, and the ↓
┆19┆┆83┆┄┄action part of the block is executed (cf. chapter 6). ↓
┆19┆┆83┆┄┄When the execution terminates the procedure call is ↓
┆19┆┆83┆┄┄completed.↲
↲
Detailed rules for actual parameters are decribed in section ↓
6.1.↲
↲
↲
┆8c┆┆83┆┆c8┆↓
┆b0┆┆a1┆5.7 Jump Statements↲
↲
The statements described in this section serve to explicitly ↓
modify the order of execution of statements by transferring ↓
control to an implicitly or explicitly indicated statement.↲
↲
↲
┆b0┆┆a1┆5.7.1 Exitloop Statement↲
↲
Execution of an exitloop statement causes the execution of ↓
an enclosing repetitive statement (cf. section 5.5) to ↓
terminate.↲
↲
↲
↲
↲
The repetition exited is the innermost one. An exitloop ↓
statement may only appear within a repetitive statement, ↓
i.e. repeat, for, while or loop statement.↲
↲
┆a1┆Example:↲
The generalized loop control structure may be constructed as ↓
a combination of a loop statement, an if statement, and an ↓
exitloop statement:↲
↲
LOOP↲
  s_1_1; ...; s_1_n;↲
  IF bool_condition THEN EXITLOOP;↲
  s_2_1; ...; s_2_m↲
ENDLOOP↲
↲
↲
┆b0┆┆a1┆5.7.2 Continueloop Statement↲
↲
The continueloop statement specifies that the remaining part ↓
of an iterationof a loop is to be skipped.↲
↲
↲
↲
↲
┆8c┆┆83┆┆e0┆↓
The statement applies to the innermost enclosing repetitive ↓
statement which must therefore exist. Depending on the kind ↓
of repetition statement (cf. section 5.5) the specific ↓
effect of the continueloop statement is:↲
↲
┆a1┆for statement:↲
Step 4 terminates, and execution continues at step 5.↲
↲
┆a1┆loop statement:↲
Execution continues with the first statement after LOOP.↲
↲
┆a1┆while statement:↲
The remainder of the statement following DO is skipped. ↓
Execution continues with the evaluation of the loop ↓
condition.↲
↲
┆a1┆repeat statement:↲
The remainder of the statement sequence up to UNTIL is ↓
skipped. Execution continues with the evaluation of the loop ↓
condition.↲
↲
↲
┆b0┆┆a1┆5.7.3 Exit Statement↲
↲
An exit statement has the effect of a jump to the END of the ↓
compound statement of the enclosing block.↲
↲
↲
↲
↲
Executionof an exit statement causes termination of the ↓
execution of the action part of the nearest enclosing ↓
routineor program block as if the compound statement had ↓
been exhausted.↲
↲

════════════════════════════════════════════════════════════════════════
↓
┆a1┆Example:↲
BEGIN (* main program *)↲
  ...↲
  IF errors-detected THEN (* terminate the process *)↲
    EXIT;↲
  ...↲
END↲
↲
↲
┆b0┆┆a1┆5.7.4 Goto and Labelled Statement↲
↲
The execution of a goto statement results in an explicit ↓
transfer of control to another statement specified by a ↓
label.↲
↲
↲
↲
↲
↲
↲
↲
A labelled statement introduces the label name as denoting a ↓
label of the 'statement' following:.↲
↲
A labelled statement is executed by executing the ↓
'statement'.↲
↲
Execution of a goto statement causes the normal order of ↓
execution of the statements within a compound statement to ↓
be broken. Executionis resumed at the labelled statement ↓
whose 'label_name' is identical to the one occurring in the ↓
goto statement. The label must be visible at the point where ↓
the goto statement occurs.↲
↲
A goto statement cannot be used to transfer control from the ↓
outside into or from the inside out of the statement ↓
following DO of a for, with, lock, or region statement.↲
↲
┆a1┆Note:↲
Goto into or out of a block is impossible.↲
↲
↲
┆8c┆┆83┆┆f8┆↓
┆b0┆┆a1┆5.8 With Statement↲
↲
A with statement may be used for three purposes:↲
↲
- shorthand notation for field access in a record object,↲
- object renaming,↲
- object retyping.↲
↲
The latter is the facility allowing a programmer-defined ↓
type to be superimposed on a buffer when applied in a lock ↓
statement.↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
The denoted object is called the ┆a1┆with-object┆e1┆. It must not be ↓
an irregular object (cf. section 3.9). The type specified by ↓
the 'common type specification', if present, is called the ↓
┆a1┆local type┆e1┆. The type of the with-object must not be ↓
protected, nor may the local type. The size of the local ↓
type must be less than or equal to the size of the with-↓
object.↲
↲
If the AS-part of a with statement is empty several with-↓
objects may be listed. More specifically↲
    WITH d┆82┆1┆81┆, d┆82┆2┆81┆, ..., d┆82┆n┆81┆ DO st↲
is acceptable as shorthand for↲
    WITH d┆82┆1┆81┆ DO WITH d┆82┆2┆81┆ DO ... WITH d┆82┆n┆81┆ DO st↲
where the d┆82┆1┆81┆ are object denotations.↲
↲

════════════════════════════════════════════════════════════════════════
↓
A with statement is executed in three steps:↲
a. ┆84┆the denotation of the with-object is evaluated as an ↓
┆19┆┆83┆┄┄object expression, i.e. the address of the object is ↓
┆19┆┆83┆┄┄established;↲
2. the local type, if present, is established;↲
3. ┆84┆the statement following DO is executed observing the ↓
┆19┆┆83┆┄┄rules described below.↲
↲
┆a1┆field access:↲
If the type of the with-object is a record tye and fname is ↓
a field name of this record type then↲
    fname↲
may be used as shorthand for↲
    obj.fname↲
where obj is an object denotation denoting the with-object.↲
↲
┆a1┆renaming:↲
a non-empty AS-part is equivalent to a local declaration of ↓
an object, called the ┆a1┆local object┆e1┆, with the same address as ↓
the with-object. The 'local_name' denotes the local object.↲
↲
┆a1┆retyping:↲
The type of the local object is the local type, if ↓
specified; otherwise it is the type of the with-object.↲
↲
┆a1┆Notes:↲
the with-object is not restricted to be of a record type, ↓
even (structured) constants are allowed.↲
↲
The address of the object is evaluated only once before the ↓
statement following DO is executed.↲
↲
The retyping of an object is a low-level facility of the ↓
language, intended for use in connection with buffers whose ↓
exact type is not known beforehand (some of the type ↓
information may be part of the buffer contents). But the ↓
facility may be used freely to achieve a relaxation of the ↓
otherwise rigorous object typing, which is one of the basic ↓
features of the language. this method demands an explicit ↓
┆8c┆┆83┆┆d4┆↓
and clear retyping stated where it is used in the program, ↓
in contrast to the standard Pascal solution using variant ↓
records.↲
↲
The effect of assignment of exchange between partially ↓
overlapping objects is undefined.↲
↲
┆a1┆Example:↲
Let rec_var be a record with a field named rec_field, and ↓
let local_type contain a field named loc_rec_field, then the ↓
fields may be accessed in the following ways in the ↓
statement following DO:↲
↲
1) ┆84┆WITH rec_var DO (* the well-known standard Pascal form *)↲
   rec_var.rec_field or↲
   rec_field↲
↲
2) WITH rec_var AS loc_var DO (* simple renaming *)↲
   rec_var.rec_field or↲
   rec_field         or↲
   loc_var.rec_field↲
↲
3) WITH rec_var AS loc_var: local_type DO↲
   (* renaming and retyping *)↲
   rec_var.rec_field or↲
   rec_field         or↲
   loc_var.loc_rec_field↲
↲
┆a1┆Exampel:↲
TYPE↲
  cat_record= RECORD ↲
                title:  ....↲
╞	╞	  author: ....↲
╞	╞	END;↲
VAR↲
  b_catalog: ARRAY(1..cat_size) OF cat_record;↲
  search_object: cat_record;↲
          ...↲
┆8c┆┆83┆┆c8┆↓
  WITH search_object AS s_o DO↲
    WHILE NOT found DO↲
      WITH b_catalog(current_index) DO↲
        IF author(* of b_catalog *) <> s_o.author then↲
          current_index:=current_index+1↲
        ELSE↲
          ...↲
↲
↲
┆b0┆┆a1┆5.9 Lock Statement↲
↲
The lock statement is the language construct which provides ↓
access to the actual contents of a buffer, i.e. to the top ↓
non-empty buffer in a buffer stack.↲
↲
↲
↲
↲
↲
↲
↲
↲
The denoted object must be a variable of type reference or ↓
chain. If it is a reference its value must not be NIL, and ↓
if it is a chain it must not be empty. Otherwise a fault ↓
occurs. The buffer designated by the reference, or the ↓
current buffer of the chain, whichever applies, may be ↓
accessed in the statement following DO as an implicitly ↓
declared variable the name of which is specified by the ↓
'buffer_name'. Either the whole buffer or only its data is ↓
accessible, depending on the 'lockword'.↲
↲
If the 'lockword' is LOCK the data area is accessible as a ↓
variable of a type belonging to the predefined family↲
    dataarea(offset, top: 0..maxint)=↲
╞	╞	╞	  PACKED AREA(offset..top-1) OF byte ↓
where the parameter values are equal to the buffer ↓
attributes with the same names. The address of the variable ↓
┆8c┆┆83┆┆c8┆↓
as well as the parameter values are evaluated before the ↓
statement following DO is executed.↲
↲
If the 'lockword' is LOCKBUF the whole buffer is accessible ↓
as a variable of a type belonging to the predefined family↲
    buffer(bufsize: 1..maxint)= ↲
                    PACKED ARRAY(0..bufsize-1) OF byte↲
where the value of the parameter equals the size of the ↓
buffer.↲
↲
If a lock statement is applied to a buffer stack with no ↓
non-empty buffer a fault occurs.↲
↲
The following restrictions are imposed on the use of the ↓
locked variable while the statement following DO is being ↓
executed, including any routine calls made: If a reference, ↓
it must not be used as part of an exchange statement or as a ↓
parameter to signal, return, or putbuf (cf. chapter 9), or ↓
be delivered to the IMC (cf. chapter 11). Whether a chain or ↓
a reference, it must not be used as a parameter to any of ↓
the buffer stack or chain manipulation routines (cf. chapter ↓
10). However, it is legal to (cynamically) apply multiple ↓
locks to the same reference or chain (e.g. in a routine ↓
called from within a lock statement).↲
↲
┆a1┆Example:↲
LOCK ref TO data_part DO↲
  WITH data_part AS data : my_buffer_type DO↲
    ...↲
↲
↲
┆b0┆┆a1┆5.10 Region Statement↲
↲
The region statement provides access to shared variables and ↓
it is ensured that the access is exclusive.↲
↲
↲
↲
↲
┆8c┆┆83┆┆d4┆↓
The denoted object must be a shared variable. Associated ↓
with every shared variable is an ┆a1┆access count┆e1┆ which is ↓
initially zero. A region statement is executed in three ↓
steps.↲
↲
1. ┆84┆Unless the process executing the region statement is ↓
┆19┆┆83┆┄┄already executing (dynamically inside) a region statement ↓
┆19┆┆83┆┄┄accessing the same shared variable it waits (is ↓
┆19┆┆83┆┄┄suspended) until the access countof the variable is zero. ↓
┆19┆┆83┆┄┄Subsequently the access count is incremented. If several ↓
┆19┆┆83┆┄┄processes wait for access to the same shared variable ↓
┆19┆┆83┆┄┄they observe a fifo discipline.↲
↲
2. ┆84┆The statement following DO is executed. In this statement ↓
┆19┆┆83┆┄┄the shared variable may be accessed in the same fashion ↓
┆19┆┆83┆┄┄as an ordinary (private) variable.↲
↲
3. The access count of the shared variable is decremented.↲
↲
┆a1┆Example:↲
↲
VAR↲
  route_table: RECORD↲
    ...↲
  PROCEDURE close_down(node: node_ident);↲
    ...↲
    REGION route_table DO↲
      route_table.open_routes(node):=closed;↲
      ...↲
↲

════════════════════════════════════════════════════════════════════════
↓
┆b0┆┆a1┆6. PROGRAMS AND ROUTINES↲
↲
Programs and routines are very similar. Both have the ↓
general form of a heading followed by a block. Incarnations ↓
of program and routine blocks also exhibit fundamental ↓
similarities. In both cases the life of an incarnation has ↓
three stages: parameter passing, elaboration of ↓
declarations, and execution of an action part. The ↓
differences have to do with two aspects: control and ↓
environment.↲
↲
An incarnation of a program block is a process on its own ↓
which lives autonomously except for the control exercised by ↓
its parent, whereas an incarnation, or ┆a1┆activation┆e1┆, of a ↓
routine block is merely an episode in the life of a process. ↓
The activation, unless it chooses to loop infinitely or ↓
commits a fault, has no choice but to return to the point ↓
where it was called.↲
↲
A process has no environment of data to acces apart from ↓
predefined items and its parameters. A routine block ↓
activation, in addition to these, has its static ↓
surroundings: all the stack-allocated objects (including ↓
formal parameters) declared in enclosing blocks, except ↓
those which have been made invisible by redeclaration of ↓
their names, cf. chapter 8.↲
↲
A program declaration may appear at the outer level of a ↓
'compilation unit', cf. section 8.2, or in the delcaration ↓
part of a program block. It serves to name and define a ↓
program.↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
┆8c┆┆83┆┆e0┆↓
The heading specifies the name of the program and its formal ↓
parameters, if any.↲
↲
A routine declaration may also appear at the outer level of ↓
a 'compilation unit', or in the declaration part of a block. ↓
It serves to name and define a routine.↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
The initial keyword in a routine heading specifies whether ↓
the routine is a function or a procedure. In addition the ↓
declaration specifies the name of the routine, its formal ↓
parameters, if any, and in the case of a function: its ↓
result type, which must be an ordinal, machine or pointer ↓
type. The 'routine block' unless specified by one of the ↓
keywords EXTERNAL or FORWARD (see blow) is associated with ↓
the function of procedure name.↲
↲
The parameters and blocks of programs as well as routines ↓
are described in the following two sections.↲
↲
┆a1┆Example:↲
PROGRAM router (INSPECT routs: route_table)↲
FUNCTION search_name(name: name_node): boolean↲
PROCEDURE insert_name(VAR position: table_index↲
╞	╞	        name: name_record)↲
↲
┆b0┆┆a1┆↲

════════════════════════════════════════════════════════════════════════
↓
┆b0┆┆a1┆6.1 Parameters↲
↲
The 'formal parameters' of a program or routine heading ↓
specify the names, kinds and types of the formal arametersof ↓
the program or routine.↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
Each 'formal_name' introduceds one parameter. Several ↓
parameters may be named in a list, separated by commas. Such ↓
parameters have the same kind and type.↲
↲
The kind of a parameter, which may be ┆a1┆variable┆e1┆, ┆a1┆inspect┆e1┆, ↓
┆a1┆shared┆e1┆ or ┆a1┆value┆e1┆, is specified by the (possible) keyword ↓
preceding its name. In the block of the program or routine ↓
each parameter acts as an object. The parameter kind ↓
determines how this object may be used:↲
↲
┆a1┆keyword╞	parameter kind╞	use of object╞	╞	╞	╞	╞	↲
VAR╞	╞	variable╞	╞	as a private variable↲
INSPECT╞	inspect╞	╞	as a constant↲
SHARED╞	shared╞	╞	as a shared variable↲
none╞	value╞	╞	as a private variable↲
↲
The type of each parameter, i.e. of the object which can be ↓
accessed in the block of the rogram or routine, is ↓
determined by the 'formal type specification' following the ↓
name of the parameter. If the 'formal type specification' is ↓
a 'parameterized-type_name', i.e. the name of a family of ↓
conformant types, the type of the formal parameter is ↓
determined for each incarnation of the program or routine by ↓
the type of the actual parameter.↲
↲
┆8c┆┆83┆┆d4┆↓
An incarnation of a program or routine is created as a ↓
result of a 'create call', 'function call', or 'procedure ↓
call' being evaluated or executed. The call contains a ↓
description of the actual parameters to be bound to the ↓
formal parameters for the particular incarnation of the ↓
program or routine.↲
↲
↲
↲
↲
↲
↲
Each actual parameter corresponds to the formal parameter in ↓
the same position in the 'formal parameters'. The number of ↓
actual parameters must equal the number of formal ↓
parameters. An actual parameter of kind variable, inspect, ↓
or shared must be of the same type as the corresponding ↓
formal parameter. An actual parameter of kind value need ↓
only be assignable to the formal parameter (cf. section ↓
3.10). When the type of a formal parameter is specified as ↓
the name of a family of types the type of the corresponding ↓
actual parameter may be any type in that family.↲
↲
The symbol ? may be used in place of an actual parameter ↓
expression when the parameter is not of kind value, ↓
regardless of the type of the formal parameter.↲
↲
The binding of an actual parameter to the corresponding ↓
formal parameter takes place either by a value transfer ↓
("call by value"), or by an address transfer ("call by ↓
reference") depending on the kind of the parameter. Value ↓
parameters are passed by value transfer, all other kinds by ↓
address transfer.↲
↲
┆a1┆value transfer:↲
The value of the actual parameter becomes the initial value ↓
of the formal parameter which is allocated on the stack as ↓
an object local to the incarnation.↲
↲
┆8c┆┆83┆┆d4┆↓
┆a1┆address transer:↲
The actual parameter is an object expression, cf. chapter 4. ↓
It must not denote an irregular object (cf. section 3.9). ↓
Evaluation of the actual parameter yields the address of an ↓
object of the parameter type. Throughout the life of the ↓
incarnation of the program or routine the formal parameter ↓
name will denote this object.↲
↲
An actual parameter object passed to a process must be ↓
declared at the outer block level of the parent process, ↓
i.e. either it must itself be a process parameter or it must ↓
be declared in the program declaration part.↲
↲
If the actual parameter is specified as ? there is no ↓
parameter object. If an attempt is made to access such a ↓
non-existing parameter object a fault occurs.↲
↲
If the kind of the formal parameter is varialbe the actual ↓
parameter object must be a private variable or component of ↓
a private variable. If the kind of the formal parameter is ↓
shared the actual parameter object must be a shared ↓
variable. Conversely, if the actual parameter is shared, the ↓
kind of the formal parameter must also be shared.↲
↲
The following restrictions apply to process parameters, i.e. ↓
to the formal parameters which occur in a program heading:↲
- ┆84┆parameters of kind variable must be of type pool, mailbox, ↓
┆19┆┆82┆┄┄or port;↲
- ┆84┆parameters (or components thereof) of pointer types must ↓
┆19┆┆82┆┄┄have mailbox as their base type, regardless of kind.↲
↲
┆a1┆Notes:↲
An actual process parameter of kind inspect may be a ↓
variable, and thus it may be changed by the parent process.↲
↲

════════════════════════════════════════════════════════════════════════
↓
┆a1┆Example:↲
TYPE↲
   list= ARRAY(1..max_list_length) OF list_element;↲
↲
   PROCEDURE handle_list(INSPECT 1st: list);↲
   -- 1st is of kind inspect to save time and space, and to↲
   -- allow the handling of constant lists↲
↲
↲
┆b0┆┆a1┆6.2 Incarnations of Blocks↲
↲
A block, whether program or routine, consists of a ↓
declaration part and an action part which has the form of a ↓
compound statement.↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
Blocks specified by one of the keywords EXTERNAL and FORWARD ↓
are described in subsection 6.2.2.↲
↲
The declaration parts of program and routine blocks are ↓
slightly different in that certain forms of declarations may ↓
not occur in a routine block; see subsection 6.2.1.↲
↲
An incarnation, whether of a program or routine, is created ↓
in the following three steps.↲
↲

════════════════════════════════════════════════════════════════════════
↓
1) ┆84┆Allocation of the necessary (initial) amount of stack and ↓
┆19┆┆83┆┄┄heap. In the case of a program this means a whole new ↓
┆19┆┆83┆┄┄stack; in the case of a routine it means an ┆a1┆activation ↓
┆19┆┆83┆┄┆84┆record┆e1┆ in the stack of the calling process.↲
↲
2) Parameter passing, cf. section 6.1.↲
↲
3) ┆84┆Elaboration of the declarations of the blocks, as ↓
┆19┆┆83┆┄┄described below.↲
↲
When an incarnation has been created the actions part of the ↓
block can be executed, cf. function call (section 4.2), ↓
procedure call (section 5.6), and create call (section 9.1).↲
↲
When execution of the action part of a routine terminates ↓
the values of all local reference variables must be NIL, ↓
otherwise a fault occurs.↲
↲
↲
┆b0┆┆a1┆6.2.1 The Declaration Part↲
↲
The declaration part of a block names and defines types, ↓
objects, routines and programs which are local to the block, ↓
i.e. not visible outside the block. The names introduced in ↓
the declarations may be used within the block to refer to ↓
the defined entities, cf. chapter 8.↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
┆8c┆┆83┆┆e0┆↓
Variables of shielded types, except reference, and variables ↓
which have components of these types may not be declared in ↓
a routine declaration part, i.e. such variables can only be ↓
declared in the outer block of a program.↲
↲
The declarations in the declaration part of a block are ↓
elaborated in the order of occurrence. Elaboration of type ↓
declarations is described in section 3.2, elaboration of ↓
variable and shared declarations is described in subsection ↓
3.12.2, and constant declarations need no elaboration at ↓
run-time.↲
↲
The elaboration of a routine or program declaration causes ↓
all types defined in the 'formal parameters' to be ↓
established. When a program declaration is elaborated a ┆a1┆sub-↓
┆19┆┄┄┆84┆program object┆e1┆ is allocated in the stack of the process ↓
being created, and associated with the program name ↓
specified in the declaration. Unless the program block is ↓
external, the sub-program object is linked (as if by an ↓
implicit link call, cf. chapter 9) to the block; otherwise ↓
it is initialized as having state unlinked.↲
↲
The elaboration of the declaration part is performed for ↓
each incarnation of a block, and the names introduced in the ↓
declarations, when occurring in the remainder of the block, ↓
refer to those instances of the named entities which have ↓
been established or allocated when the particular ↓
incarnation of the block was created.↲
↲
In the case of a function block elaboration of the ↓
declaration part, even if it is empty, includes ↓
establishment of the result type and allocation on the stack ↓
of an implicitly declared ┆a1┆result object┆e1┆. The initial value ↓
of the result object is undefined.↲
↲
┆a1┆Note:↲
The static environment of an internal program block is the ↓
same as that of the enclosing program block, i.e. only names ↓
┆8c┆┆83┆┆c8┆↓
in contexts specified for the compilation unit, cf. chapter ↓
8, predefined names, and the names of formal parameters are ↓
known from the start of the block.↲
↲
Elaboration of declarations is not the only time types may ↓
be established. Further types may be established when for, ↓
with, and lock statements are executed.↲
↲
┆b0┆┆f0┆┆a1┆Example (of nested routines):↲
↲
TYPE parity= (even, odd);↲
↲
FUNCTION byte_parity(arg: byte): parity;↲
↲
  FUNCTION even4bits(arg: 0..15): boolean;↲
    CONST table= (. 0,3,5,6,9,10,12,15 .);↲
  BEGIN even4bits:=arg IN table END;↲
↲
BEGIN (* byte parity *)↲
  IF even4bits(int(arg SHIFT (-4))) -- left half byte↲
    =even4bits(int(arg AND  HF))    -- right half byte↲
  THEN byte_parity:=even↲
  ELSE byte_parity:=odd↲
END↲
↲
↲
┆b0┆┆a1┆6.2.2 Forward and External Blocks↲
↲
A forward announcement of a declaration containing the ↓
actual block of a routine may be given by using the keyword ↓
FORWARD in place of the routine block. When a forward ↓
announcement is used a declaration with an identical routine ↓
heading, i.e. all lexical elements identical, and an actual ↓
routine block (i.e. constisting of declaration part, which ↓
may be empty, and action part) must appear later in the same ↓
'declaration part'. In this way it is possible to observe ↓
the rule of declaration before use, even for mutually ↓
recursive routines.↲
↲
┆8c┆┆83┆┆d4┆↓
The block of a program or routine may be specified as ↓
external, i.e. separately compiled (cf. chapter 8), by the ↓
keyword EXTERNAL. This may only be used in the declaration ↓
part of a block appearing at the outermost block level of a ↓
compilation unit, cf. section 8.2. An external program or ↓
routine y possibly be written in another programming ↓
language and compiled by a compiler for that language ↓
provided it is object code format compatible with the Real-↓
Time Pascal compiler in question.↲
↲
Due to the differences between routines and programs the ↓
linking of a program to a separately compiled block is ↓
somewhat different in the two cases.↲
↲
During the execution of an incarnation of a program ↓
containing an external program declaration the linking ↓
between the resulting sub-program object and the block of a ↓
separately compiled program is established as a result of ↓
the evaluation of an explicit link call, cf. chapter 9.↲
↲
The association between the block of a separately compiled ↓
routine and the function or procedure name specified in an ↓
external routine delcaration, i.e. the linking of the ↓
routine block to the program in which the external ↓
declaration occurs, must be established by a linkage editor ↓
before an incarnation of the program can be created. This ↓
can be done during a separate link-phase following ↓
compilation, or it can be done as a by-effect of program ↓
linking at run-time.↲
↲
The amount and kind of checking of the agreement between the ↓
'formal parameters' of an external program or routine ↓
declaration and the corresponding formal parameter ↓
specificationof the separately compiled block, which is ↓
performed during linking, is implementation dependent. This ↓
is true for both cases of linking. In order to facilitate ↓
linking with programs written in other languages the ↓
parameter and result passing formats used by an ↓
┆8c┆┆83┆┆c8┆↓
implementation must be appropriately chosen and thoroughly ↓
documented.↲
↲
┆a1┆Example (of mutually recursive routines):↲
↲
PROCEDURE first(par1, par2: type1); FORWARD;↲
↲
PROCEDURE second(par: par_type);↲
  ...↲
BEGIN↲
  ...↲
  first(act1, ct2);↲
  ...↲
END;↲
↲
PROCEDURE first(part1, par2: type1);↲
  ...↲
BEGIN↲
  ...↲
  second(act);↲
  ...↲
END↲
↲
↲
┆b0┆┆a1┆6.2.3 The Action Part↲
↲
Execution of the actions of a block means execution of its ↓
compound statement. This is described in chapter 5. ↓
Executionis ┆a1┆terminated┆e1┆ when the compound statement is ↓
exhausted, when an exit statement is executed, or when a ↓
fault occurs. When a process terminates it goes into a ↓
passive state where it remains until removed by its parent. ↓
When a procedure activation terminates its activation record ↓
is deallocated and a return is made to the caller, i.e. the ↓
procedure call is completed. When a function activation ↓
terminates its activation record is deallocated and the ↓
final value of the implicit result object is the value of ↓
the function call whose evaluation caused the activation.↲
↲

════════════════════════════════════════════════════════════════════════
↓
┆b0┆┆a1┆7. FAULT HANDLING↲
↲
A number of violationsof the rules of Real-Time Pascal are ↓
referred to in this document as faults. Faults are errors ↓
which cannot, at least not in call cases, be detected at ↓
compile-time. Faults which are detected at compile-time ↓
cause the compiler to reject the source program. When a ↓
fault occurs at run-time, during the execution of an ↓
incarnation of a program, the following happens:↲
↲
1. ┆84┆The ┆a1┆exception procedure┆e1┆ of the program is called with a ↓
┆19┆┆83┆┄┄fault code parameter indicating the kind of fault which ↓
┆19┆┆83┆┄┄occurred.↲
2. ┆84┆When (if) the exception procedure returns the process ↓
┆19┆┆83┆┄┄terminates and goes into a passive state as if execution ↓
┆19┆┆83┆┄┄of its action part had been completed.↲
↲
Fault codes are implementation dependent and must be ↓
documented for each implementation.↲
↲
↲
┆b0┆┆a1┆7.1 Default Exception Procedure↲
↲
Every implementation must include a default exception ↓
procedure which outputs a snapshot of the stack of the ↓
calling process and the fault code.↲
↲
The default exception procedure may also be called to ↓
provide trace information about a process. Such an explicit ↓
call does not cause the process to terminate. The heading of ↓
the default exception procedure is:↲
↲
PROCEDURE trace(fault: integer)↲
↲
↲

════════════════════════════════════════════════════════════════════════
↓
┆b0┆┆a1┆7.2 Programmer-defined Exception Procedure↲
↲
When a procedure with the name exception and one integer-↓
type parameter, i.e.↲
↲
PROCEDURE exception(fault: integer)↲
↲
is declared (internally) at the outer block level of a ↓
program, this procedure becomes the exception procedure of ↓
the program.↲
↲
┆a1┆Note:↲
An ordinary call of a programmer-defined exception procedure ↓
does not cause a process to terminate.↲
↲

════════════════════════════════════════════════════════════════════════
↓
┆b0┆┆a1┆8. NAMING ENVIRONMENTS↲
↲
The rules described in this chapter serve to define for ↓
every point in a Real-Time Pascal source text the ┆a1┆naming ↓
┆19┆┄┄┆84┆environment┆e1┆ which is valied at that point. A naming ↓
environment it must have an independent meaning, i.e. an ↓
occurrence of the name must denote a ┆a2┆┆e2┆┆a1┆program entity┆e1┆ ↓
irrespective of the syntactic context. A program entity is a ↓
value, a type, a family of conformant types, an object ↓
(which may in particular be a formal parameter), a label, a ↓
routine, or a (sub-)program. The visibility rules ensure ↓
that the entity denoted by a name is always uniquely ↓
determined.↲
↲
In other words, the purpose of this chapter is to answer the ↓
question: When a name occurs at some point in a source text, ↓
what does it mean? and to ensure that the meaning is ↓
uniquely defined.↲
↲
The unit of compilation for a Real-Time Pascal compiler is ↓
basically a sequence of routine and/or program declarations, ↓
referred to in the following as a ┆a1┆source text┆e1┆. The ↓
visibility rules for names introduced in a source text are ↓
described in section 8.1, and the precise syntactic form of ↓
a compilation unit is described in section 8.2 along with a ↓
discussion of the role played by predefined names and names ↓
introduced in so-called contexts.↲
↲
↲
┆b0┆┆a1┆8.1 Visibility Rules↲
↲
All names which occur in a source text must hve one or more ↓
points of ┆a1┆introduction┆e1┆ each of which defines a program ↓
entity which can be denoted by the name within some region ↓
of the text, called the ┆a1┆visibility region┆e1┆ of the entity. The ↓
point of introduction may be a declaration, a formal ↓
parameter specification, a labelled statement, the AS-part ↓
of a with statement, the iteration description of a for ↓
┆8c┆┆83┆┆c8┆↓
statement, or a 7buffer_name' in a lock statement. Every ↓
introduction of a name has a ┆a1┆scope┆e1┆, i.e. a region of text ↓
over which the introduction has an effect. The concept of ↓
scope serves as a tool in determining the visibility region ↓
of a named program entity.↲
↲
Once the visibility regions of all program entities are ↓
known the determination of a naming environment proceeds as ↓
follows: Consider a name occurring at some point in a ↓
program. If the point is within the visibility region of a ↓
program entity whose name is the name under consideration, ↓
then the name denotes that program entity. Otherwise it has ↓
no meaning, i.e. it is not part of naming environment.↲
↲
There are two kinds of names which have no independent ↓
meaning, but whose meaning is dependent on the syntactic ↓
context, viz. the names of record fields and formal type ↓
parameters. However, because of the shorthand form of record ↓
field access allowed in with statements (cf. section 3.8) ↓
the names of fields of a with-object of a record type are ↓
treated as if introduced in the 'with definition'. Apart ↓
from this special case the names of record fields and type ↓
parameters are not members of naming environments.↲
↲
Three kinds of rules which together make up the visibility ↓
rules are given below:↲
↲
- uniqueness rules: ┆84┆rules which serve only to prevent ↓
┆19┆┆94┆┄┄ambiguous meanings of names,↲
- scope rules:      ┆84┆rules which determine the scope of an ↓
┆19┆┆94┆┄┄introduction of a name,↲
- exclusion rules:  ┆84┆rules which determine the visibility ↓
┆19┆┆94┆┄┄region of a program entity by explicit ↓
┆19┆┆94┆┄┄exclusion of sub-regions from the scope ↓
┆19┆┆94┆┄┄of the introduction of the name of the ↓
┆19┆┆94┆┄┄entity.↲
↲

════════════════════════════════════════════════════════════════════════
↓
┆a1┆Uniqueness rules↲
↲
The following names are said to be introduced ┆a1┆initially┆e1┆ in a ↓
block:↲
↲
- ┆84┆the names of the formal parameters specified in the ↓
┆19┆┆82┆┄┄heading of the block,↲
- ┆84┆the names of program entities introduced in the ↓
┆19┆┆82┆┄┄declaration part of the block exclusing the formal ↓
┆19┆┆82┆┄┄parameter lists and blocks of enclosed program and routine ↓
┆19┆┆82┆┄┄declarations, and↲
- ┆84┆the names of labels appearing in the compound statement of ↓
┆19┆┆82┆┄┄the block.↲
↲
1) ┆84┆All names introduced initially in a block must be ↓
┆19┆┆83┆┄┄distinct.↲
2) ┆84┆All names introduced in the 'with definition' of a with ↓
┆19┆┆83┆┄┄statement must be distinct.↲
↲
┆a1┆Scope rules↲
↲
1) ┆84┆The scope of a label or variable name is the compound ↓
┆19┆┆83┆┄┄statement of the block in which it is introduced.↲
2) ┆84┆The scope of any other name introduced initially in a ↓
┆19┆┆83┆┄┄block extends from the point of introduction to the end ↓
┆19┆┆83┆┄┄of the block. This is the rule which implies that in ↓
┆19┆┆83┆┄┄general a name must be introduced before use.↲
3) ┆84┆The scope of the 'for_name' introduced in a for ↓
┆19┆┆83┆┄┄statement, or of a name introduced in a lock statement is ↓
┆19┆┆83┆┄┄the 'statement' following DO in the for, with, or lock ↓
┆19┆┆83┆┄┄statement.↲
4) ┆84┆The scope of a record field name introduced as field ↓
┆19┆┆83┆┄┄access shorthand in a with statement is the statement ↓
┆19┆┆83┆┄┄following DO.↲
↲
┆a1┆Exclusion rules↲
↲
An introduction of a name which occurs within the stope of a ↓
previous introduction of the same name is called a ↓
┆a1┆reintroduction┆e1┆.↲
↲
┆8c┆┆83┆┆ec┆↓
The visibility region of a named program entity is the scope ↓
of the introduction of its name with the following possible ↓
exceptions:↲
↲
1) Any inner program blocks.↲
2) ┆84┆The scope(s) of any reintroduction(s) of the name, i.e. ↓
┆19┆┆83┆┄┄reintroduction hides the entity denoted by the outer ↓
┆19┆┆83┆┄┄occurrence of the name.↲
↲
┆a1┆Example:↲
↲
Hiding of an entity by reintroductionof its name is ↓
illustrated below:↲
↲
PROCEDURE p;↲
CONST↲
   n=2;↲
   ...↲
   PROCEDURE q;↲
   CONST↲
      m=n; (* 2 *)↲
      n=5;↲
   BEGIN↲
      ... n ... (* has value 5 *)↲
   ...↲
END↲
↲
↲
┆b0┆┆a1┆8.2 Contexts and Predefined Names↲
↲
The initial naming environment of a compilation consists of ↓
the predefined names and entities and those introduced in ↓
contexts.↲
↲
The unit of compilation is a sequence of program and/or ↓
routine declarations optionally preceded by one or more ↓
contexts. A compiler must allow contexts to be supplied as ↓
files separate from the source text proper.↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
┆8c┆┆84┆┆f0┆↓
All names introduced in one context must be distinct. The ↓
names introduced in contexts and theprogram entities defined ↓
at their points of introduction are treted as if they were ↓
introduced in a block surrounding the outer block(s) of the ↓
source text proper with one exception: the exclusion rule ↓
for inner program blocks does not apply. The scope of a name ↓
introduced in a context extends from the point of ↓
introduction to the end of the compilation unit. Routines ↓
declared in a context must be external, i.e. the actual ↓
block of a routine cannot be specified in a context.↲
↲
The scope of names predefined as part of the language, cf. ↓
Appendix C, is the complete compilation unit. As with ↓
contexts the exclusion rule for inner program blocks does ↓
not apply to predefined entities. However, a predefined name ↓
may be hidden by reintroduction.↲
↲
┆a1┆Note:↲
the exclusion rule for inner program blocks implies that ↓
types, constants, and routines which are to be common for ↓
several programs compiled as one unit must be specified in a ↓
context.↲
↲

════════════════════════════════════════════════════════════════════════
↓
┆14┆┆b3┆┆b0┆┆06┆┆0b┆↲
┆b0┆┆a1┆9. PROCESS CONTROL AND INTER-COMMUNICATION↲
↲
This chapter describes the predefined language constructs ↓
available for control of offspring processes and for ↓
exchange of information between processes.↲
↲
An incarnation of a sub-program is called a child of a ↓
(parent) process which is an incarnation of the program ↓
containing the sub-program declaration.↲
↲
The navel string between the parent and the child is a ↓
variable of type process belonging to the parent. An ↓
arbitrary number of incarnations of a sub-program may be ↓
born; they are all controlled by the parent.↲
↲
When a child is born it is supplied with actual parameters ↓
according to the formal parameter specifiction of the ↓
declaration, cf. section 6.1. Processes communicate via ↓
mailboxes or shared variables. A mailbox or a shared ↓
variable known by a parent may be made known as a paramter ↓
to its children (such a variable may either be owned by the ↓
parentor one of its ancestors). In this way a parent ↓
determines the communication paths of its children without, ↓
however, necessarily participating in the communication ↓
itself. Refer to section 5.10 for communication by means of ↓
shared variables and section 9.2 for mailbox communication.↲
↲
↲
┆b0┆┆a1┆9.1 Process Control↲
↲
A sub-program declaration in a program implies the ↓
allocation of a sub-program object in the stack of an ↓
incarnation of theprogram. The states of a sub-program ↓
object are ┆a1┆linked┆e1┆ and ┆a1┆unlinked┆e1┆, cf. section 6.2.1 for the ↓
initial state of a subprogram object.↲
↲
The linking (i.e. change of state from unlinked to linked) ↓
is performed by a link call which is similar to a function ↓
call.↲
↲
↲
↲
↲
┆8c┆┆84┆┆84┆↓
The type of the result of alink call is an implementation ↓
dependend predefined enumeration type↲
 link_result= (link_ok, already_linked, external_not_found, ↓
               ...).↲
↲
The purpose of a link call is to find a suitable program ↓
block matching the sub-program declaration. The value of the ↓
expression, which must be of a string type, is used to ↓
search for the program block in a fashion which is ↓
implementation dependent. the 'formal parameters' of the ↓
sub-program declaration may also be used in the match. If a ↓
program block is found it is linked to the sub-program ↓
object denoted by the 'program_name'.↲
↲
The result of a link call indicates that the linking was ↓
successful or why it went wrong.↲
↲
If the implementation and installation allows dynamic ↓
program load, the executionof a link call may involve the ↓
loading of a suitable program as well as the necessary ↓
linkage editing.↲
↲
If a new program block is to be linked to a sub-program ↓
object, the former link must be broken, i.e. the state of ↓
the sub-program object has to be changed from linked to ↓
unlinked. This is done by means of an unlink call, which is ↓
similar to a function call:↲
↲
↲
↲
↲
The result of an unlink call is of the implementation ↓
dependent predefined enumeration type↲
  unlink_result= (unlink_ok, no_program_linked,↲
╞	╞	    existing_incarnations, ...)↲
↲
After the call, if successful, the sub-program object may be ↓
linked anew (link call).↲
↲
┆8c┆┆83┆┆d4┆↓
Processes may be created as incarnations of sub-programs in ↓
the linked state. When a process has been created it will ↓
begin to execute its actions. A process may become ↓
temporarily unable to execute actions for two reasons, which ↓
are independent of each other. It may be ┆a1┆waiting┆e1┆ for an ↓
event, cf. subsection 9.2.2, or ┆a1┆stopped┆e1┆, cf. the predefined ↓
procedures stop and resume described below. A process is ↓
only able to execute actions if it is neither waiting nor ↓
stopped. The dynamic allocation of processor time to ↓
processes with the latter property is the scheduling ↓
function performed by the operating system or language-↓
supporting nucleus.↲
↲
A process is created by means of a create call.↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
↲
The evaluation of a create call causes an incarnation of the ↓
program block linked to the sub-program object denoted by ↓
'program_name' to be created as described in section 6.2. If ↓
the state of the sub-program object is unlinked a fault will ↓
occur. When a process has just been created it is neither ↓
stopped nor waiting.↲
↲
The value of the 'name_expression', which must be of a ↓
string type, is attached to the created process for ↓
diagnostic purposes.↲
↲
The 'process_object denotation' denotes the variable through ↓
which the calling process will control the child; it must be ↓
┆8c┆┆83┆┆c8┆↓
of type process. The value of this variable must be NIL ↓
before the call, otherwise a fault occurs. After the call it ↓
will be a reference to the child process. ↓
↲
The 'actual parameters' of the program call are bound to the ↓
corresponding formal parameters as part of the evaluation of ↓
the create call.↲
↲
The initial size of the stack which is allocated for the ↓
created procedss is determined by the value of the ↓
'size_expression' which must be of type 0..maxint. Size 0 ↓
means allocation of an area according to a value defined for ↓
the sub-program at compile-time, cf. chapter 12. The unit of ↓
measurement for stack size is implementation dependent.↲
↲
The value of the 'priority_expression' determines the ↓
execution priority of the created process. This quantity ↓
affects the way in which the process is scheduled for ↓
executionin a fashion which depends on the implementation. ↓
The type required of the expression also depends on the ↓
implementation.↲
↲
The result of a create call has an implementation dependent ↓
predefined enumeration type↲
    create_result= (create_ok, no_memory, ...).↲
↲
If the create call was unsuccessful the result will indicate ↓
the reason. In this case no process will have been created ↓
and the value of the process variable will still be NIL.↲
↲
The predefined procedures stop, resume, and remove may be ↓
used to control a child, designated by a process variable ↓
passed as a parameter. If one of the procedures is called ↓
with this variable equal to NIL a fault will occur.↲
↲
PROCEDURE stop(VAR pr: process)↲
↲
┆8c┆┆83┆┆bc┆↓
The child process becomres stopped. If it is already stopped ↓
before the call there is no effect.↲
↲
PROCEDURE resume(VAR pr: process)↲
↲
If the child process is stopped a call of resume makes it ↓
not stopped; otherwise the call has no effect.↲
↲
PROCEDURE remove(VAR pr: process)↲
↲
A call of remove causes the child process to be removed, ↓
i.e. execution of its action part is terminated and all ↓
resources owned by the child are released and become free ↓
memory. The resources include stack, heap, and pools. Any ↓
ports owned by the process are closed (cf. section 11.1). ↓
Pools and buffers are handled as follows:↲
↲
1. ┆84┆All buffers which have a pool owned by the child process ↓
┆19┆┆83┆┄┄as their home pool are marked for deallocation. A special ↓
┆19┆┆83┆┄┄treatment is given to a buffer stack whose top buffer is ↓
┆19┆┆83┆┄┄marked for deallocation, in the following situations:↲
↲
   - ┆84┆A process calls putbuf (cf. section 3.8) attempting to ↓
┆19┆┆85┆┄┄put the buffer in its home pool (in this case the ↓
┆19┆┆85┆┄┄buffer must be alone in the stack), ↓
↲
   - ┆84┆A process calls return (cf. subsection 9.2.2) ↓
┆19┆┆85┆┄┄attempting to place the stack in the return address ↓
┆19┆┆85┆┄┄mailbox of the top buffer,↲
↲
   - ┆84┆An attempt is made to place the stack in the return ↓
┆19┆┆85┆┄┄address mailbox of the top buffer as an IMC event (cf. ↓
┆19┆┆85┆┄┄chapter 11) or as described below.↲
↲
   ┆84┆In all three cases the special treatment is the ↓
┆19┆┆83┆┄┄following. First the top buffer is removed from the stck ↓
┆19┆┆83┆┄┄and released to become free memory. Then the remainder of ↓
┆19┆┆83┆┄┄the stack, if non-empty, is placed in the return address ↓
┆8c┆┆83┆┆c8┆↓
┆19┆┆83┆┄┄mailbox of the new top buffer, except if this buffer is ↓
┆19┆┆83┆┄┄also marked for deallocation in which case the rule ↓
┆19┆┆83┆┄┄applies recursively. The event kind attribute of a buffer ↓
┆19┆┆83┆┄┄returned in this fashion becomes process_removed.↲
↲
2. ┆84┆All buffer stacks accessed through reference or chain ↓
┆19┆┆83┆┄┄variables or presently placed in mailboxes owned by the ↓
┆19┆┆83┆┄┄child process are placed in the return address mailbox of ↓
┆19┆┆83┆┄┄the top buffer with the event kind attribute equal to ↓
┆19┆┆83┆┄┄process_removed. If the top buffer is marked for ↓
┆19┆┆83┆┄┄deallocation the above rule applies.↲
↲
If the process to be removed has any children, these are ↓
removed before the process itself. This rule applies ↓
recursively. Thus, in effect, removal of a process means ↓
removal of that subtree of the complete process three of ↓
which the process is the root.↲
↲
After a call of remove the value of the parameter is NIL.↲
↲
If a process shares a pool with a child, i.e. if the pool ↓
was passed as a process parameter when the child process was ↓
created, the process must not remove that child. If an ↓
attempt is made a fault occurs. However, if the process ↓
itself is removed, the child will also be removed by the ↓
recursion described above.↲
↲
It is illegal to remove a child process while it is ↓
executing a region statement. An attempt to do so causes a ↓
fault.↲
↲

════════════════════════════════════════════════════════════════════════
↓
┆a1┆Example:↲
↲
link_res:=link("child1", my_child);↲
IF link_res <> link_ok THEN link_error(link_res);↲
create_res:=create("child_1_1", my_child(mbx1), process1, 0, ↓
           std_prio);↲
IF create_res <> create_ok THEN create_error(create_res);↲
create_res:=create(Wchild_1_2", my_child(mbx2), process2, 0, ↓
           std_prio);↲
IF create_res <> create_ok THEN create_error(create_res);↲
  ...↲
stop(process6);↲
  ...↲
resume(process6);↲
  ...↲
remove(process4);↲
create_res:=create("child_2_4", my_child(alternative_mbx),↲
                   process4, 200, high_prio);↲
IF ...↲
  ...↲
↲
↲
┆b0┆┆a1┆9.2 Mailbox Communication↲
↲
Messages may be passed among processes via mailboxes. A ↓
message is the contents of a stack of buffers, which is ↓
accessed through a variable of type reference or chain. At ↓
most one reference or chain variable holds a reference to a ↓
buffer at any time; thus mutually exclusive access to ↓
buffers is ensured.↲
↲
Access to the data contained in a buffer is only possible in ↓
a lock statement (cf. section 5.9).↲
↲
The access right is exchanged between processes by means of ↓
the predefined procedures signal, wait, waitdelay, and ↓
return as described in subsection 9.2.2.↲
↲
↲
┆8c┆┆83┆┆d4┆↓
┆b0┆┆a1┆9.2.1 Mailbox States↲
↲
A mailbox may be regarded as a waiting room in one of the ↓
states passive, open or locked:↲
↲
passive:↲
┆a1┆   mbx  ↲
          Neither buffers to be accessed nor processes ↓
┆a1┆        ┆e1┆  asking for access at the mailbox.↲
↲
 open:↲
┆a1┆   mbx  ┆e1┆  A list of buffers (actually buffer stacks) are ↲
  buf1    ready for access, the first one will be removed↲
  buf2    from the list when a process asks for a buffer,↲
  buf3    and the process will be given the access right.↲
┆a1┆  buf4  ↲
↲
locked:↲
┆a1┆   mbx  ┆e1┆  A list of processes are waiting for access to a ↲
  proc1   buffer; the first one will get the access right to↲
  proc2   the next buffer arriving at the mailbox and will↲
  proc3   subsequently be removed from the list.↲
┆a1┆  proc4 ↲
↲
There are three predefined boolean functions to inspect the ↓
state of a mailbox. However, it is not mandatory that these ↓
functions be implemented.↲
↲
FUNCTION open(VAR mbx: mailbox): boolean↲
FUNCTION locked(VAR mbx: mailbox): boolean↲
FUNCTION passive(VAR mbx: mailbox): boolean↲
↲
↲
┆b0┆┆a1┆9.2.2 Communication and Synchronization Primitives↲
↲
There are four predefined communication/synchronization ↓
primitives: signal, return, wait, and waitdelay. In addition ↓
the delay primitive may be used for purposes of ↓
synchronization or temporary process suspension.↲
↲
┆8c┆┆83┆┆e0┆↓
Signal is performed by a call of the predefined procedure ↓
signal:↲
↲
PROCEDURE signal(VAR mbx: mailbox; VAR ref: reference)↲
The value of ref must not be NIL or the reference locked ↓
(cf. section 5.9), otherwise a fault occurs. After the call, ↓
the buffer designated by ref is entered as the last element ↓
of the list of buffers belonging to mbx. If the mailbox is ↓
locked, the first process is removed from the list of ↓
waiting processes. This process is now allowed to complete ↓
the call of wait/waitdelay which caused its insertion in the ↓
list of the mailbox. The event kind attribute of the ↓
designated buffer becomes message_event.↲
↲
The language provides two kinds of events which can be ↓
waited for:↲
- the arrival of a buffer at a specified mailbox.↲
- ┆84┆the expiry of a delay, specified as a number of ↓
┆19┆┆82┆┄┄milliseconds. An implementation need not, however, support ↓
┆19┆┆82┆┄┄such fine granularity. If the delay is specified as zero, ↓
┆19┆┆82┆┄┄the call (delay, waitdelay, or getbufdelay) will return ↓
┆19┆┆82┆┄┄immediately.↲
↲
A process may wait for one specific event or for the first ↓
one of two, one of each kind. It does so by calling one of ↓
the following routines.↲
↲
PROCEDURE wait(VAR mbx: mailbox; VAR ref: reference)↲
The value of ref must be NIL prior to a call, otherwise a ↓
fault occurs. If the mailbox mbx is open, the first buffer ↓
stack in the list is removed and ref will designate this ↓
stack. If the mailbox state is locked or passive the process ↓
is suspended until one of the events eventually occurs. The ↓
result indicates the reason why the process is activated; ↓
its type is the predefined enumeration type↲
   wait_result= (a_buffer, a_delay).↲
↲
┆8c┆┆83┆┆bc┆↓
Getting a buffer from a pool, cf. section 3.8, is similar to ↓
receiving a buffer from a mailbox. A special version of ↓
getbuf is therefore available which allows the specification ↓
of a maximum delay which a process will tolerate.↲
↲
FUNCTION getbufdelay(VAR p: pool; VAR ra: mailbox;↲
         VAR r: reference; no_of_msecs: 0..maxint): ↓
                wait_result↲
↲
The description of getbuf, cf. section 3.8, applies also to ↓
getbufdelay with the modification that in case the delay ↓
specified by no_of_msecs expires before the calling process ↓
obtains a buffer the call will return the result a_delay and ↓
otherwise have no effect. If a buffer is obtained the result ↓
will be a_buffer.↲
↲
Return is performed by a call of the predefined procedure ↓
return:↲
↲
PROCEDURE return(VAR ref: reference)↲
The call:╞	╞	return(ref)↲
is equivalent to:╞	signal(ret_address, ref)↲
where ret_address denotes the return address of the buffer ↓
designated by ref, cf. section 3.8, except for the value of ↓
the event kind attribute which becomes answer_event.↲
↲
┆a1┆Notes:↲
A mailbox may be inspected without hving to wait if it is ↓
empty by calling waitdelay with zero delay.↲
↲
An implementation must secure indivisibility of the ↓
communication primitives.↲
↲
┆a1┆Example:↲
The following communication flow is possible by means of ↓
signal and return. Each process p┆82┆i┆81┆ must know the (mailbox) ↓
address of process pi+1┆81┆. However, process p┆82┆n┆81┆ does not know ↓
process p┆82┆1┆81┆.↲
↲
┆8c┆┆83┆┆d4┆↓
  signal╞	signal╞	╞	signal↲
↲
↲
  p┆82┆1┆81┆       p┆82┆2┆81┆            ...             p┆82┆n┆81┆↲
↲
 ╞	╞	   return↲
↲
↲

════════════════════════════════════════════════════════════════════════
↓
┆b0┆┆a1┆10. BUFFER MANIPULATION↲
↲
Two structures for organizaing buffers are supported by the ↓
language: stacks and chains. A buffer stack is the general ↓
form of a message, where a stack with only one buffer is a ↓
special case. Access to a stack may be transferred between ↓
processes via a mailbox (cf. section 9.2). The chain ↓
structure is intended for local organization of buffers in ↓
aprocess. The elementsof a chain are buffer stacks. They are ↓
accessed by a handle: a variable of type chain. The elements ↓
of a buffer stack are buffers. They are accessed by a ↓
handle: a reference variable (or directly by a chain in the ↓
case of the current buffer). The manipulation of buffer ↓
stacks is described in section 10.1 and of chains in section ↓
10.2.↲
↲
↲
┆b0┆┆a1┆10.1 Buffer Stacks↲
↲
A stack is one or more buffers, organized as a lifo list so ↓
that manipulation affects the youngest member only. Access ↓
to the data in a stack of buffers is achieved by means of a ↓
lock statement, possibly giving access to several members of ↓
the stack (cf. secion 5.9).↲
↲
Access to the attributes of buffers in a stack can only be ↓
made to those of the top (youngest) member. A special ↓
treatment is given to the size and data description ↓
attributes when empty buffers are pushed onto or popped from ↓
a stack, ensuring that these attributes will apply to the ↓
topmost non-empty buffer in the stack, since only non-empty ↓
buffers can be accessed in a lock statement.↲
↲
A stack may be manipulated by calling the predefined ↓
procedures push and pop. The parameters to these procedures ↓
must not be locked. Otherwise a fault will occur at the time ↓
of call.↲
↲
┆8c┆┆83┆┆c8┆↓
PROCEDURE push(VAR stack_handle, new_top: reference)↲
↲
The parameter new_top must designate a buffer stack with ↓
only one element, otherwise a fault occurs. The buffer stack ↓
designated by stack_handle, possibly an empty stack (i.e. ↓
the handle is NIL), is extended with the buffer designated ↓
by new_top as the new top element. After the call ↓
stack_handle will designate the new stack, and the value of ↓
new_top will be NIL.↲
↲
If the new top buffer is empty, and the stack was not empty ↓
before pushing, the size and data area description (offset, ↓
top, and byte count) are copied from the old to the new top ↓
buffer.↲
↲
PROCEDURE pop(VAR stack_handle, popped_buf: reference)↲
↲
The value of popped_buf must be NIL, and the value of ↓
stack_handle must not be NIL; otherwise a fault occurs. The ↓
result of a call of pop is: the top buffer in the stack is ↓
removed, popped_buf will designate a stack consisting of the ↓
removed buffer only, and stack_handle will designate the ↓
remaining part of the stack. If the stack had only one ↓
element its value will be NIL.↲
↲
If the popped buffer is empty, its size and data area ↓
description attributes (offset, top, and byte count) are all ↓
set to zero.↲
↲
The depth of a buffer stack as well as the number of actual ↓
data buffers can be obtained by using the predefined ↓
functions stckdepth and bufcount.↲
↲
FUNCTION stackdepth(VAR stack: reference): 0..maxint↲
FUNCTION bufcount(VAR stack: reference): 0..maxint↲
↲
The value returned by stackdepth is the total number of ↓
buffers in the designated stack, including empty ones, ↓
┆8c┆┆83┆┆c8┆↓
whereas bufcount yields only the number of non-empty buffers ↓
(cf. lock statement, section 5.9). Both functions return the ↓
value 0 if the parameter has value NIL.↲
↲
┆a1┆Example:↲
The following flow of buffers may be achieved by means of ↓
the paired operations: (push, signal) and (pop, return).↲
↲
  ╞	(signal)╞	╞	(push, signal)╞	(push, signal)↲
↲
↲
p╞	╞	p       ...╞	 p╞	╞	  p↲
 ┆81┆1             2                    n-1                  n↲
↲
╞	(pop, return)╞	(pop, return)╞	(return)↲
↲
↲
┆b0┆┆a1┆10.2 Buffer Chains↲
↲
The initial state of a chain object is empty, i.e. the ↓
length of the chain is 0. Cyclic lists are built and ↓
manipulated by means of predefined routines only. The ↓
following actions may be performed on chains: insert an ↓
element, extract an element, change current buffer, update ↓
start point, and read the length.↲
↲
Two elements of a chain have a special status:↲
↲
- ┆84┆the ┆a1┆start point┆e1┆ of the chain is the first element put into ↓
┆19┆┆82┆┄┄the chain or an element explicitly selected as the start ↓
┆19┆┆82┆┄┄point.↲
↲
- ┆84┆the ┆a1┆current buffer (stack)┆e1┆ is the element which may be ↓
┆19┆┆82┆┄┄extracted or accessed in a lock statement and the only ↓
┆19┆┆82┆┄┄element whose buffer attributes may be read or changed.↲
↲
The predefined routines eventkind, resetevent, u1, u2, u3, ↓
u4, setu1, setu2, setu3, setu4, bufsize, offset, top, ↓
┆8c┆┆83┆┆c8┆↓
bytecount, setoffset, settop, and setbytecount which are ↓
described in section 3.8 may all be called with a chain ↓
object as parameter, in which case they apply to the current ↓
stack (top buffer) of the chain.↲
↲
The length of a chain is read by means of a call of the ↓
function chainlength:↲
↲
FUNCTION chainlength(VAR ch: chain): 0..maxint↲
↲
For all the routines described in the remainder of this ↓
section the parameter (chains and references) must not be ↓
locked. Otherwise a fault occurs at the time of call.↲
↲
A buffer stack is inserted into a chain by means of a call ↓
of chaininsert:↲
↲
PROCEDURE chaininsert(VAR ch: chain; VAR ref: reference)↲
↲
The value of ref must not be NIL, otherwise a fault occurs. ↓
The stack designated by ref becomes the new current buffer f ↓
the list, the element is inserted as the successor of the ↓
element which was the current buffer prior to the call, and ↓
the value of ref becomes NIL.↲
↲
The current buffer may be removed from a list by meansof a ↓
call of chainextract:↲
↲
PROCEDURE chainextract(VAR ch: chain; VAR ref: reference)↲
↲
The value of ref must be NIL, otherwise a fault occurs. If ↓
the length of the chain ch is 0 a fault occurs. The current ↓
buffer is removed from the chain and will be designated by ↓
ref. the successor of the removed element becomes the new ↓
current buffer. If the start point is removed from a list ↓
with more than one element the successor of the removed ↓
element becomres the new start point as well as the new ↓
current buffer.↲
↲
┆8c┆┆83┆┆d4┆↓
The current buffer may be moved one step up or down the ↓
list, or moved to the start point by calling the procedures ↓
chainup, chaindown and chainstart respectively:↲
↲
PROCEDURE chainup(VAR ch: chain)↲
PROCEDURE chaindown(VAR ch: chain)↲
PROCEDURE chainstart(VAR ch: chain)↲
The result of a call of chainup/chaindown/chainstart is that ↓
the successor/predecessor/start point becomes the new ↓
current buffer of the list.↲
↲
The current buffer of a list may be made the new start point ↓
of a list by a call of chainreset:↲
↲
PROCEDURE chainreset(VAR ch: chain)↲
↲
┆a1┆Example:↲
Let ch be the handle of a sorted chain of buffers:↲
↲
chainstart(ch);↲
FOR count:=1 TO chainlength(ch) DO↲
BEGIN↲
  chainextract(ch, work_ref);↲
  push(result_stack, work_ref)↲
END(*FOR*);↲
signal(mail_center, result_stack)↲
↲

════════════════════════════════════════════════════════════════════════
↓
┆b0┆┆a1┆11. IMC FUNCTIONS↲
↲
The concept of a resident module is introduced in (4) as a ↓
well defined entity, which is self-contained in terms of ↓
resources. In Real-Time Pascal a resident is thus a tree of ↓
processes whose root does not enherit any resources. That ↓
is, no pool or port is made known to the root of the ↓
resident as a process parameter. However, the concept of ↓
resident is not reflected in the syntax of Real-Time Pascal ↓
or in rules enforced by the language.↲
↲
Residents exist in a destributred environment and ↓
communicate with eachother by using the standard inter ↓
module communication (IMC) services (5). The embedding of ↓
these services into Real-Time Pascal is the scope of the ↓
present chapter. In the remainder of the chapter the ↓
software components at the IMC nodes plus the physical ↓
interconnection media which together provide the IMC ↓
services are referred to as the IMC network or just the IMC.↲
↲
A resident gains access to IMC services via objects of the ↓
type port. Port names, in turn, establish the identification ↓
of residents towards the IMC network and towards one ↓
another. Port names consist of a maximum of 12 graphic ↓
characters. Communication between two residents takes place ↓
as transfers of strings of bytes from buffers belonging to a ↓
sender to buffers belonging to a receiver. an actual ↓
transfer within the IMC network takes place when both ↓
residents have delivered a buffer to the IMC.↲
↲
The principal means of communication is connections between ↓
two ports. On a connection the IMC perform flow control, ↓
correct sequencing, and undamaged data transfer.↲
↲
The relationship between invokation and completion of IMC ↓
functions is asynchronous. IMC services are invoked by calls ↓
of predefined service request routines. In most cases a call ↓
of a rquest routine causes the transfer of a buffer (or two) ↓
┆8c┆┆83┆┆c8┆↓
from the calling resident to the IMC. When the requested ↓
function has been carried out this buffer, called an ┆a1┆event ↓
┆19┆┄┄┆84┆buffer┆e1┆, will be returned, i.e. to its return address ↓
mailbox, with relevant result information andpossibly ↓
containing received data. The return of an event buffer to a ↓
resident is called an ┆a1┆IMC event┆e1┆, or just an event. The ↓
interface between residents and the IMC has been designed so ↓
that no change, which is of significance to a resident, in ↓
the state of a port or connection end-point can take place ↓
without the occurrence of an event, unless it occurs during ↓
a call of a request routine and as a direct consequence of ↓
this call. In other words, despite the asynchronous nature ↓
of the interface, residents always have complete up-to-date ↓
information about their ports and connections.↲
↲
During the time-span from an event buffer has been ↓
transferred to the IMC until it is eventually returned it is ↓
said to be outstanding. An outstanding event buffer may be ↓
further characterized by the kind of event it is intended to ↓
retrieve. All IMC events correspond to values of the ↓
predefined enumeration type event_type which is given in ↓
section 3.8. All IMC events are described in the following ↓
sections.↲
↲
In some cases the IMC will return an event buffer even ↓
though the intended event has not occurred, most often ↓
because circumstances change so that it never will. This is ↓
called a dummy event. As an example, an outstanding data ↓
buffer is returned as a dummy event when the connection to ↓
which it pertains is unexpectedly removed. A number of ↓
event_type values are used exclusively for dummy events. ↓
Each of these values indicates the event which the dummy ↓
event buffer had been set up to retrive. The correspondence ↓
between dummy event kinds and intended event kinds is shown ↓
below:↲
↲

════════════════════════════════════════════════════════════════════════
↓
┆a1┆dummy event╞	╞	intended event┆05┆↲
dummy_letter╞	╞	letter_arrived↲
dummy_lcnct╞	╞	local_connect↲
dummy_rcnct╞	╞	remote_connect↲
dummy_rindic╞	╞	reset_indication↲
dummy_rcmpl╞	╞	reset_completion↲
dummy_credit╞	╞	credit↲
dummy_sent╞	╞	data_sent↲
dummy_arrived╞	╞	data_arrived↲
↲
In addition to request routines Real-Time Pascal provides ↓
routines which can decode event information by inspecting ↓
the IMC buffer attributes used to carry this information.↲
↲
The IMC service request routines are described in the ↓
following three sections. With a single exception (connect, ↓
see subsection 11.3.2) the reference type parameters to ↓
these routines must not have value NIL or be locked when a ↓
call is made; otherwise a fault will occur. These parameters ↓
are used to transfer event buffer to the IMC, and they ↓
always have value NIL after a call.↲
↲
The IMC never changes the size, offset, top, or u-attributes ↓
of an event buffer. With the exception of actual data ↓
buffers (sendletter, receiveletter, send, receive, ↓
receiveall) is always placed in the data area of the receive ↓
buffer, and the number of bytes it comprises is assigned to ↓
the byte count attribute.↲
↲
The data area description of the buffer passed by a call of ↓
a data transfer routine must be consistent, cf. section 3.8. ↓
Otherwise a fault occurs.↲
↲
↲
┆b0┆┆a1┆11.1 Ports↲
↲
An IMC port is represented in Real-Time Pascal as a variable ↓
of type port. The state of a port is either open, in which ↓

════════════════════════════════════════════════════════════════════════
↓
case the port is known in the IMC network by a name which is ↓
puslished according to its scope, or closed (or closing, see ↓
under closeport below).↲
↲
An open port contains a number of connection end-points (cf. ↓
section 11.3). The number must not be greater than an ↓
implementation dependent maximum, cf. section 11.5).↲
↲
The attributes of a port, i.e. name, scope, and number of ↓
endpoints, are defined when it is opened by a call of ↓
openport:↲
↲
PROCEDURE openport(VAR p: port; VAR closebuf: reference;↲
╞	╞	     INSPEC name: string; scope: scope_type;↲
╞	╞	     no_of_cons: 0..maxint; rcv_all: boolean)↲
where p is the port to be opened. The parameter closebuf ↓
designates the port_closed event buffer which will be ↓
outstanding while the port is open. The values of the name ↓
and scope parameters specify the name of the port and the ↓
range within the IMC network in which to publish the name. ↓
The value of no_of_cons is the number of connection end-↓
points requested for the port. If this number is greater ↓
than the maximum allowed or if the length of the name is ↓
greater than 12 a fault will occur.↲
↲
The type of the scope parameter is the predefined ↓
enumeration type↲
╞	scope_type= (anonymous, local, regional, global).↲
For a further discussion of scopes, see (5).↲
↲
The call causes the port to be opened as requested. The ↓
state of the port must be closed when the call is made, ↓
otherwise a fault occurs. After the call the state of the ↓
port is open. The port_closed event will occur when it is ↓
eventually closed with one of the following reasons (cf. ↓
section 11.4):↲
↲
╞	reason_ok:╞	the resident called closeport↲
╞	reason_name:╞	a name-conflict arose↲
╞	reason_resource:╞	┆84┆resource problem somewhere in the ↓
┆19┆┆98┆┄┄IMC network.↲
↲
┆8c┆┆83┆┆f8┆↓
If the value of the parameter rcv_all is true, the general ↓
receive feature (cf. receiveall, subsection 11.3.2) is ↓
enabled for the port; otherwise it is not.↲
↲
A port is withdrawn from the IMC network by a call of  ↓
closeport:↲
↲
PROCEDURE closeport(VAR p: port)↲
↲
where p is the port to be closed. If the port is already ↓
closed the call has no effect. Otherwise it proceeds as ↓
follows. All connections on the port are removed with ↓
graceful completion of any feasible data transfers as ↓
described for disconnect, cf. subsection 11.3.2. The ↓
disconnected events occur with reason_closed. However, at ↓
the remote end of a connection the disconnected event occurs ↓
with reason_ok. Then all general receive and letter receive ↓
buffer are returned as dummy events, and finally the ↓
port_closed event occurs with reason_ok. The port is made ↓
unknown to the IMC network, its state changes to closed, and ↓
it may subsequently be re-opened, possibly with a different ↓
set of attributes. While connections are being removed and ↓
buffers returned the port is said to be closing.↲
↲
↲
┆b0┆┆a1┆11.2 Letters↲
↲
The most primitive form of data transfer supported by the ↓
IMC is a letter which may be transferred directly to a ↓
destination port without the overhead of establishing a ↓
connection, without flow control or end-to-end control, and ↓
without the guarantee of delivery.↲
↲
In order to receive a letter a resident must call ↓
receiveletter:↲
↲
PROCEDURE receiveletter(VAR p: port; VAR databuf: reference)↲
↲
┆8c┆┆83┆┆c8┆↓
where p is the receiving port and databuf designates the ↓
receive buffer. If theport is closed or closing the receive ↓
buffer is returned as a dummy event and the call has no ↓
further effect. Otherwise the receive buffer will be ↓
outstanding until a letter arrives and then be returned as ↓
letter_arrived. Letters are truncated to fit into a receive ↓
buffer, if necessary.↲
↲
A letter is sent by means of a call of sendletter:↲
↲
PROCEDURE sendletter(INSPECT destination: string;↲
╞	╞	       VAR databuf: reference)↲
↲
where databuf designates the send buffer containing the ↓
letter to be sent, and the destination parameter is the name ↓
of the receiving port.↲
↲
When a letter is sent towards a receiving resident, the send ↓
buffer is returned as letter_sent. This does not imply that ↓
the letter will actually be delivered, only that an attempt ↓
will be made. The letter may be lost due to buffer shortage ↓
in the IMC network, because the receiver has no outstanding ↓
buffer for arriving letters, or because the port name is ↓
unknown.↲
↲
If the size of a letter is greater than an implementation ↓
dependent maximum, cf. maxlettersize (section 11.5), it may ↓
be truncated during transfer through the IMC network. ↓
Neither sender nor receiver will be notified in this case.↲
↲
↲
┆b0┆┆a1┆11.3 Connections↲
↲
Connections are the principal means of data transfer between ↓
residents. A connection joins two connection end-points, ↓
each contained in an open port. Before a connection can be ↓
established one of the two residents must make a connection ↓
end-point available by calling getconnection (cf. subsection ↓
┆8c┆┆83┆┆c8┆↓
11.3.2). The resident which calls getconnection is the ↓
passive part in the establishment of the connection and need ↓
not know the name of the remote port. The other resident is ↓
the active part which must specifically request that a ↓
connection be established by calling connect (cf. subsection ↓
11.3.2).↲
↲
An end-point within a port is identified in a request call ↓
by a pair (p, index) where p is a port and index is a number ↓
in the range 1..n, where n equals the value of no_of_cons ↓
given when the port was opend. This fact accounts for the ↓
first two parameters of all the rquest routines described in ↓
this section (except receiveall). If a request call is made ↓
iwth an index parameter which is out of range a fault ↓
occurs.↲
↲
Notice that end-point indices are local to a port and not ↓
related to indices or even known at the remote end-points of ↓
connections.↲
↲
Each kind of request call which may be made concerning a ↓
connection end-point is only permitted provided the end-↓
point is in an appropriate state. The applicable states are:↲
↲
free:╞	 ┆84┆the end-point is free for use by calling ↓
┆19┆┆8f┆┄┄connect or getconnection. Free is the initial ↓
┆19┆┆8f┆┄┄state of connection end-points contained in a ↓
┆19┆┆8f┆┄┄newly opened port,↲
accept_remote: ┆84┆getconnection has been called. The end-point ↓
┆19┆┆8f┆┄┄will leave this state when a connection is ↓
┆19┆┆8f┆┄┄established from a remote port, or when ↓
┆19┆┆8f┆┄┄disconnect is called,↲
connected:╞	 ┆84┆a connection has been or is being ↓
┆19┆┆8f┆┄┄established, and data transfer may take ↓
┆19┆┆8f┆┄┄place,↲
resetting:╞	 ┆84┆reset has been called while the state was ↓
┆19┆┆8f┆┄┄connected. The state will revert to connected ↓
┆19┆┆8f┆┄┄when the resetting procedures have been ↓
┆19┆┆8f┆┄┄completed,↲
┆8c┆┆83┆┆d4┆↓
disconnecting: ┆84┆disconnect has been called, and the process ↓
┆19┆┆8f┆┄┄of removing a previous connection is under ↓
┆19┆┆8f┆┄┄way. The state will subsequently become free.↲
↲
If the end-point identification (p, index) given in a ↓
request call is such that the port is closed or closing, or ↓
the state of the end-point is free, the connection to which ↓
the call pertains is said to be ┆a1┆absent┆e1┆. This phenomenon may ↓
occur if the event which informs the resident about the ↓
removal of a connection or the closing of a port has not ↓
been processed at the time of call.↲
↲
It is a general rule that if a request call is made ↓
concerning a connection end-point which is in a wrong state ↓
for the call a fault occurs, except if the connection is ↓
absent.↲
↲
↲
┆b0┆┆a1┆11.3.1 Connection Administration↲
↲
A connection end-point is made available for remotely ↓
initiated connection establishment by a call of ↓
getconnection:↲
↲
PROCEDURE getconnection(VAR p: port; index: 1..maxint;↲
╞	╞	    ╞	VAR compl, disc: reference)↲
If the port is closed or closing the buffer designated by ↓
compl is returned as a dummy event and the buffer designated ↓
by disc as a disconnected event with reason_closed, and the ↓
call has no further effect. Otherwise a call of ↓
getconnection is only permitted if the state of the end-↓
point is free; after the call it is remote_accpet. The ↓
buffer designated by compl will be returned as a ↓
remote_connect event when a connection has been established. ↓
The buffer designated by disc will be the disconnected ↓
buffer of the connection end-point. It will be outstanding ↓
until the end-point becomes free again.↲
↲
┆8c┆┆83┆┆c8┆↓
In order to establish a connection between a local ↓
connection end-point and a remote end-point, which has been ↓
made available as described above, a resident must call ↓
connect:↲
↲
PROCEDURE connect(VAR p: port; index: 1..maxint;↲
╞	╞	    VAR compl, disc: reference;↲
╞	╞	    INSPECT remote_name: string:↲
╞	╞	    service: conn_service)↲
If the port is closed or closing the buffer designated by ↓
compl is returned as a dummy event and the buffer designated ↓
by disc as a disconnected event with reason_closed, and the ↓
call has no further effect. Otherwise the call is only ↓
accepted if the state of the indicated end-point is free.↲
↲
The value of remote_name is the name of the remote port to ↓
which a connection is requested. If the length of the name ↓
is greather than 12 a fault occurs. The state of the (local) ↓
end-point becomes connected, i.e. data transfer calls may be ↓
made immediately following the call of connect. This does ↓
not imply that the actual path through the IMC network has ↓
been established at this time, nor in fact that it ever will ↓
be.↲
↲
The value of the parameter compl may be NIL, i.e. the ↓
designated buffer is optional. If it is present it will be ↓
used to generate a local_connect event when the actual ↓
connection has been successfully established. This event is ↓
purely informative and not associated with any change of ↓
state. If the local_connect buffer is present, but ↓
establishment of the connection fails, the buffer will be ↓
returned as a dummy event.↲
↲
The buffer designated by disc is the disconnected event ↓
buffer. It will be outstanding until the state of the ↓
connection end-point eventually reverts to free or the port ↓
is closed. If this happens because it turns out to be ↓
impossible to establish the actual connection the reason ↓
┆8c┆┆83┆┆c8┆↓
will be either reason_name, if a port with the specified ↓
name could not be found, or reason_resource, if the ↓
necessary resources were not available in the IMC network or ↓
at the remote port (no end-point with state accept_remote).↲
↲
The service parameter selects the service class of the ↓
connection. Two service classes are defined: normal and ↓
high. The treatment of service classes depends on the ↓
implementation of the IMC network. The type of the service ↓
parameter is the predefined enumeration type↲
╞	conn_service= (cs_normal, cs_high).↲
↲
A connection end-point may always be freed by a call of ↓
disconnect:↲
↲
PROCEDURE disconnect(VAR p: port; index: 1..maxint)↲
↲
If the indicated connection is absent or if the state of the ↓
connection end-point is disconnecting the call has no ↓
effect. Otherwise if the connection end-point is engaged in ↓
a connection, i.e. if its state is connected or resetting, ↓
the connection will be removed. This will be done ↓
gracefully, i.e. all data transfers for which credit is ↓
available are completed before the remaining oustanding ↓
buffers are returned. At both ends of the connection all ↓
outstanding buffers ecept the disconnected event buffers are ↓
then returned as dummy events. While this takes place the ↓
state of the (local) end-point is disconnecting. Finally the ↓
disconnected events occur (at both ends) with reason_ok, and ↓
the state becomes free.↲
↲
If the state of the connection end-point is accept_remote ↓
when disconnect is called the remote_connect buffer will be ↓
returned as a dummy event, the disconnected event will occur ↓
with reason_ok, and the state of the end-point becomes free.↲
↲
The only reason for removal of a connection which has not ↓
been discussed above (this includes removal when a port is ↓
┆8c┆┆83┆┆c8┆↓
closed, cf. section 11.1) is failure in some component of ↓
the IMC network. If a connection is broken for this reason ↓
the disconnected event will occur with reason_network after ↓
all other outstanding buffers have been returned as dummy ↓
events.↲
↲
↲
┆b0┆┆a1┆11.3.2 Connection-based Data Transfer↲
↲
The routines for data transfer on connections and for ↓
control of data buffers: send, receive, receiveall, ↓
getcredit, reset, and getreset, are described in this ↓
subsection.↲
↲
The following rule holds for calls of all these routines ↓
except receiveall: If the connection indicated by the first ↓
two parameters is absent the buffer designated by the third ↓
parameter is returned as a dummy event and the call has no ↓
further effect. Otherwise the call is only permitted if the ↓
state of the end-point is connected (or resetting in the ↓
case of getreset).↲
↲
A receive buffer is made available for a specific connection ↓
by a call of receive:↲
↲
PROCEDURE receive(VAR p: port; index: 1..maxint;↲
╞	╞	    VAR databuf: reference)↲
↲
The designated buffer becomes an outstanding receive buffer ↓
for the connection. At the remote end of the connection the ↓
call may cause either a credit or a data_sent event to ↓
occur. If both kinds of event buffer are outstanding only ↓
the data_sent event will occur. When a unit of data has been ↓
transferred from a remote send buffer to the receive buffer ↓
the latter is returned as a data_arrived event. If ↓
necessary, the received data unit is truncated to fit into ↓
the data area of the receive buffer, and in this case the ↓
event will be data_overrun.↲
↲
┆8c┆┆83┆┆d4┆↓
If the general receive feature is enabled for a port (cf. ↓
the rcv_all parameter of openport, section 11.1) a general ↓
receive buffer for the whole port, not dedicated to a ↓
particular connection, may be delivered to the IMC by a call ↓
of receiveall:↲
↲
PROCEDURE receiveall(VAR p: port; VAR databuf: reference)↲
↲
If the port is closed or closing the designated buffer is ↓
returned as a dummy event and the call has not further ↓
effect. If the general receive feature is not enabled a ↓
fault occurs. Otherwise the buffer becomes an outstanding ↓
general receive buffer. It may be used for any connection ↓
within the port. It will eventually be returned as ↓
data_arrived or data_overrun, depending on whether the ↓
received data unit had to be trancated to fit into the ↓
receive data area. The index of the connection end-point to ↓
which the data belong will be an attribute of the buffer ↓
(cf. section 11.4). In case of network failure which causes ↓
a connection on the port to be removed the buffer may be ↓
returned as a dummy event.↲
↲
A send buffer containing a unit of data to be sent on a ↓
specified connection is delivered to the IMC network by a ↓
call of send:↲
↲
PROCEDURE send(VAR p: port; index: 1..maxint;↲
╞	╞	 VAR databuf: reference)↲
↲
The designated buffer becomes an outstanding send buffer. If ↓
a receive buffer is available at the remote end or when one ↓
becomes available (call of receive or receiveall) the ↓
indicated data unit is transferred to the receive data area. ↓
Then the send buffer is returned as data_sent, and the ↓
receive buffer at the remote end as data_arrived (or ↓
data_overrun).↲
↲
┆8c┆┆83┆┆bc┆↓
Flow control information pertaining to a specified ↓
connection can be obtained from the IMC by a call of ↓
getcredit:↲
↲
PROCEDURE getcredit(VAR p: port; index: 1..maxint;↲
╞	╞	      VAR credbuf: reference)↲
↲
The designated buffer becomes an outstanding credit buffer. ↓
It is returned as a credit event when there is one or more ↓
outstanding receive buffers at the remote end of the ↓
connection (call of receive) for which credit has not been ↓
given previously. The number of such receive buffers is ↓
passed as the buffer attribute credit count (cf. section ↓
11.4). However, a credit event can only occur provided there ↓
is at least one outstanding reset_indication buffer at the ↓
connection end-point, cf. getreset.↲
↲
Data and credit buffers which are outstanding at an end-↓
point of a connection may be taken back without breaking the ↓
connection by calling reset:↲
↲
PROCEDURE reset(VAR p: port; index: 1..maxint;↲
╞	╞	  VAR compl: reference)↲
↲
In the same graceful fashion as when a connection is removed ↓
all data transfers for which credit is available are carried ↓
out first. Then the remaining data and credit buffers are ↓
returned as dummy events, but only at the local end-point. ↓
The return of receive buffers may amount to the taking back ↓
of credit which has already been given to the remote ↓
resident. In this case the resulting negative credit is ↓
passed as the credit count attribute of a reset_indication ↓
event.↲
↲
Following a call of reset the state of the (local) ↓
connection end-point will be resetting. The buffer ↓
designated by compl is the reset_completion event buffer. ↓
This event occurs after all outstanding data and credit ↓
┆8c┆┆83┆┆c8┆↓
buffers have been returned. When it occurs the state of the ↓
end-point reverts to connected.↲
↲
When a connection end-point has been reset the IMC has also ↓
reset its account of credit previously passed to the ↓
resident. Credit information obtained before resetting is ↓
therefore no longer valid.↲
↲
If credit information is used it is necessary to know when ↓
credit is taken back as a result of resetting of the remote ↓
end-point. A reset_indication buffer which is used to carry ↓
this information is made available to the IMC by a call of ↓
getreset.↲
↲
PROCEDURE getreset (VAR p: port; index: 1..maxint;↲
╞	╞	      VAR indic: reference)↲
↲
The call is permitted if the state of the connection end-↓
point is connected or resetting, but does not change the ↓
state. The buffer designated by indic becomes an outstanding ↓
reset_indication event buffer. That is, when a reset occurs ↓
at the remote end of the connection causing loss of credit ↓
this buffer is returned as reset_indication with a credit ↓
count equal to the number of credits that have been taken ↓
back.↲
↲
At least one reset_indication buffer must be outstanding ↓
before a credit event can occur, cf. getcredit. Therefore a ↓
call of getreset may trigger a credit event.↲
↲
↲
┆b0┆┆a1┆11.4 IMC Buffer Attribute Decoding↲
↲
Whenever a buffer is returned as an event the event kind ↓
attribute is set to indicate the kind of event. This ↓
attribute may be read using the predefined function ↓
eventkind, cf. section 3.8. Depending on the event kind the ↓
attributes index, credit count, and reason may be ↓
┆8c┆┆83┆┆c8┆↓
meaningful. These attributes may be read using the three ↓
functions described below. A fault will occur if one of ↓
these functions is called with a parameter with value NIL.↲
↲
FUNCTION index(VAR r: reference): 0..maxint↲
gives the index in the relevant port of the connection end-↓
point to which the event pertains. It is defined for buffers ↓
with event kind local_connect, remote_connect, disconnected, ↓
reset_completion, reset_indication, data_sent, data_arrived, ↓
data_overrun, credit, and for fummy events. If the event is ↓
dummy and there is no applicable index the result will be 0.↲
↲
FUNCTION reason(VAR r: reference): reason_type↲
gives the reason for an event. It is relevant for buffers ↓
with event kind port_closed or disconnected. The result is ↓
of the predefined enumeration type↲
╞	reason_type= (reason_ok, reason_name, reason_resource,↲
╞	╞	    reason_closed, reason_network).↲
↲
All uses of reason values are explained in the preceding ↓
sections.↲
↲
FUNCTION creditcount(VAR r: reference): 0..maxint↲
If the event kind is credit the result is the numer of ↓
receive buffers available at the remote end-point of the ↓
connection. If the event kind is reset_indication the ↓
resultis the number of credits which have been taken back by ↓
a call of reset at the remote end-point.↲
↲
↲
┆b0┆┆a1┆11.5 Miscellaneous Routines↲
↲
At teach node in an IMC network, the IMC imposes certain ↓
restrictions on users of the IMC services, namely a maximum ↓
size for a letter and a maximum number of connections to any ↓

════════════════════════════════════════════════════════════════════════
↓
one port. these two limitations can be obtained by calling ↓
the predefined routines maxlettersize and maxconnections:↲
↲
FUNCTION maxlettersize: 0..maxint↲
FUNCTION maxconnections: 0..maxint↲
↲

════════════════════════════════════════════════════════════════════════
↓
┆b0┆┆a1┆12. COMPILER DIRECTIVES↲
↲
Directives to a Real-Time Pascal compiler may be regarded as ↓
lexical separators. They have the general form:↲
╞	$ directive-name parameters end-of-line↲
given on a separate line and with parameters, if present, ↓
enclosed in parantheses. Alternatively directives may be ↓
supplied as parameters in the call of the compiler. Some of ↓
them must be specified before the first line of actual ↓
source text is met, viz. either in the compiler call or as ↓
$-directive lines in front of the outermost program/routine ↓
heading.↲
↲
The following table lists the mandatory directives. An ↓
implementation may support additional directives. The first ↓
three directives which are all used to control the ↓
appearance of a compiler listing must appear before the ↓
first line of actual source text.↲
↲
┆a1┆name╞	parameters╞	description┆05┆↲
PAGELENGTH╞	number╞	╞	maximum number of lines ↲
(default 45)╞	╞	╞	per page of listing,↲
↲
PAGEWIDTH╞	number╞	╞	maximum number of ↲
(default 120)╞	╞	╞	┆84┆characters per line of ↓
┆19┆┆a2┆┄┄listing,↲
↲
TITLE╞	"char.string"╞	┆84┆the character string is ↓
┆19┆┆a2┆┄┄placed in the title field ↓
┆19┆┆a2┆┄┄of the header line of each ↓
┆19┆┆a2┆┄┄page of the listing,↲
↲
SUBTITLE╞	"char.string"╞	┆84┆the character string is ↓
┆19┆┆a2┆┄┄placed in the subtitle ↓
┆19┆┆a2┆┄┄line of each page of the ↓
┆19┆┆a2┆┄┄listing,↲
↲
┆8c┆┆83┆┆bc┆↓
┆a1┆name╞	parameters╞	description┆05┆↲
CODE╞	none╞	╞	┆84┆causes code generated for ↓
┆19┆┆a2┆┄┄the following lines of ↓
┆19┆┆a2┆┄┄source text to be listed,↲
↲
NOCODE╞	none╞	╞	suppresses listing of ↲
(default)╞	╞	╞	generated code,↲
↲
CREATESIZE╞	number╞	╞	┆84┆determines stack size of ↓
┆19┆┆a2┆┄┄incarnations of the ↓
┆19┆┆a2┆┄┄following program(s) if ↓
┆19┆┆a2┆┄┄the value of the ↓
┆19┆┆a2┆┄┄size_expression of the ↓
┆19┆┆a2┆┄┄careate call is 0, cf. ↓
┆19┆┆a2┆┄┄section 9.1,↲
↲
INDEXCHECK╞	none╞	╞	causes checking of sub-↲
(default)╞	╞	╞	┆84┆range constraints before ↓
┆19┆┆a2┆┄┄indexing to be included in ↓
┆19┆┆a2┆┄┄code generated for the ↓
┆19┆┆a2┆┄┄following lines of source ↓
┆19┆┆a2┆┄┄text,↲
↲
NOINDEXCHECK╞	none╞	╞	┆84┆switches off index ↓
┆19┆┆a2┆┄┄checking,↓
↲
LIST╞	none╞	╞	┆84┆causes the following lines ↓
┆19┆┆a2┆┄┄of source text to be ↓
┆19┆┆a2┆┄┄listed,↲
↲
NOLIST╞	none╞	╞	suppresses listing of↲
(default)╞	╞	╞	source text,↲
↲
RANGECHECK╞	none╞	╞	causes checking of sub-↲
(default)╞	╞	╞	┆84┆range constraints before ↓
┆19┆┆a2┆┄┄assignment to be included ↓
┆19┆┆a2┆┄┄in code generated for the ↓
┆19┆┆a2┆┄┄following lines of source ↓
┆19┆┆a2┆┄┄text,↲
↲
┆8c┆┆83┆┆e0┆↓
┆a1┆name╞	parameters╞	description┆05┆↲
NORANGECHECK╞	none╞	╞	┆84┆switches off range ↓
┆19┆┆a2┆┄┄checking,╞	↲
↲
ACCESSCHECK╞	none╞	╞	┆84┆causes code to be ↓
┆19┆┆a2┆┄┄generated for every access ↓
┆19┆┆a2┆┄┄to a formal parameter ↓
┆19┆┆a2┆┄┄object which is not of ↓
┆19┆┆a2┆┄┄kind value, to check the ↓
┆19┆┆a2┆┄┄existence of the actual ↓
┆19┆┆a2┆┄┄parameter (not specified ↓
┆19┆┆a2┆┄┄as ?).↲
↲
NOACCESSCHECK╞	none╞	╞	switches off access ↲
(default)╞	╞	╞	checking.↲
↲
SET╞	╞	switch assign-╞	see below,↲
╞	╞	ment list↲
↲
IF╞	╞	expression╞	see below,↲
↲
ENDIF╞	none╞	╞	see below,↲
↲
ELSE╞	none╞	╞	see below,↲
↲
ELSEIF╞	expression╞	see below,↲
↲
Switches are compile-time variables which can only be used ↓
in the expressions occurring in IF and ENDIF directives. A ↓
switch assignment list consists of one or more switch ↓
assignments separated by commas. A switch assignment has the ↓
form (number must be integer, no radix allowed):↲
╞	name = number↲
↲
A switch assignment either introduces and sets the value of ↓
a switch, or, if the switch has been introduced in a ↓
previous switch assignment (SET directive), merely changes ↓
the value.↲
↲
┆8c┆┆83┆┆d4┆↓
The directives IF, ELSE, ELSEIF, and ENDIF provide the ↓
capability for conditional compilation. The expressions ↓
occurring in IF and ELSEIF directive must be boolean ↓
expressions obeying the standard rules of the language. The ↓
operands must be switches and integer numbers. The following ↓
operators may be used: <, <=, >=, >, =, <>, AND, OR, XOR, ↓
NOT.↲
↲
The directives for conditional compilations may be used to ↓
selectively exclude blocks of lines of source text from ↓
compilation, i.e. to cause such lines to be created as ↓
comments. When listed, each excluded line will be marked ↓
with -- appearing at the beginning of the line.↲
↲
The directive IF and ENDIF must always be used in matching ↓
pairs. ELSE and ELSEIF may optionally be used in conjunction ↓
with IF and ENDIF. A use of conditional compilation takes ↓
the following form:↲
↲
$IF expr┆82┆1↲
s1┆82┆1↲
$ELSEIF expr┆82┆2↲
s1┆82┆2↲
$ELSEIF expr┆82┆3↲
s1┆82┆3↲
...↲
$ELSEIF expr┆82┆n↲
s1┆82┆n↲
$ELSE↲
s1┆82┆n+1↲
$ENDIF↲
↲
The only mandatory parts are the IF and ENDIF directive ↓
lines and the source line(s) s1┆82┆1┆81┆. The effect is as follows: ↓
If the values of all the expressions are false then the ↓
source lines s1┆82┆1┆81┆, s1┆82┆2┆81┆, ..., s1┆82┆n┆81┆ are excluded from ↓
compilation. Otherwise let k be the smallest number such ↓
that the value of expr┆82┆k┆81┆ is true. Then s1┆82┆1┆81┆, ..., s1┆82┆k-1┆81┆, ↓
┆8c┆┆83┆┆c8┆↓
s1┆82┆k+1┆81┆, ..., s1┆82┆n┆81┆, and s1┆82┆n+1┆81┆ (if present) are excluded from ↓
compilation.↲
↲
Conditional compilation may be used at several nested ↓
levels. In the above terminology any of the s1┆82┆i┆81┆ may thus ↓
include repeated use of conditional compilation.↲
↲
┆a1┆Notes:↲
Switches and variables in the program text belong to ↓
separate name spaces and cannot be confused. The same names ↓
may be used.↲
↲
Directives occurring in comments are ignored, in particular ↓
those occurring in source lines excluded from compilation.↲
↲

════════════════════════════════════════════════════════════════════════
↓
┆b0┆┆a1┆A. REFERENCES↲
↲
(1)  The Programming Language Pascal↲
╞	 Acta Informatica, 1, 35-63, 1971↲
╞	 N. Wirth↲
↲
(2)╞	 ISO International Standard ISO/IS 7185:↲
╞	 Specification for Computer Programming Language Pascal↲
↲
(3)╞	 ISO International Standard ISO/IS 646:↲
╞	 7-bit Coded Character Set for Information Processing↲
╞	 Interchange↲
↲
(4)  RCSL No 42-i1982:↲
╞	 Distributed System Architecture↲
╞	 A Conceptual Framework for Systems Design↲
↲
(5)╞	 RCSL No 42-i1983:↲
╞	 DSA Inter Module Communication↲
╞	 Functional Description↲
↲
(6)╞	 Platon, A High Level Language for Systems Programming↲
╞	 RECAU, R-75-59↲
╞	 Jørgen Staunstrup and Sven Meiborg Sørensen↲
↲

════════════════════════════════════════════════════════════════════════
↓
┆b0┆┆a1┆B. SYNTAX DIAGRAMS↲
↲
This appendix contains all the syntax diagrams of the ↓
definition of Real-Time Pascal in an attempted natural top-↓
down reading order. Each diagram contains a reference to the ↓
section where it is introduced and where the associated ↓
semantics are explained.↲

════════════════════════════════════════════════════════════════════════
↓
↲

════════════════════════════════════════════════════════════════════════
↓
↲

════════════════════════════════════════════════════════════════════════
↓
↲

════════════════════════════════════════════════════════════════════════
↓
↲

════════════════════════════════════════════════════════════════════════
↓
↲

════════════════════════════════════════════════════════════════════════
↓
↲

════════════════════════════════════════════════════════════════════════
↓
↲

════════════════════════════════════════════════════════════════════════
↓
↲

════════════════════════════════════════════════════════════════════════
↓
↲

════════════════════════════════════════════════════════════════════════
↓
↲

════════════════════════════════════════════════════════════════════════
↓
┆b0┆┆a1┆C. PREDEFINED ENTITIES↲
↲
In section C.1 a list of predefined entities is given in ↓
alphabetical order and with reference to the sections where ↓
the entities are described. The types and pseudo-functions ↓
which are intrinsic to the language, denoted by keywords ↓
rather than predefined names, are listed in sections C.2 and ↓
C.2.↲
↲
↲
┆b0┆┆a1┆C.1 Predefind Routines, Types, Type Families, and Constans↲
↲

╱04002d4e0a0006000000000301433100000000000000000000000000000000000000000000000000050f19232d37414b555f69737d8791ff04╱

╱04002d4e0a00060000000003013c3100000000000000000000000000000000000000000000000000050f19232d37414b555f69737d8791ff04╱
↓
┆a1┆section kind╞	╞	definition┆05┆↲
3.4.3   FUNCTION  abs(n: integer): 0..maxint↲
3.8╞	    FUNCTION  allocpool (VAR p: pool;↲
╞	╞	               no_of_bufs: 1..maxint): 0..maxint↲
5.9     TYPE      buffer(bufsize: 1..maxint)=↲
╞	╞	╞	 PACKED ARRAY(0..bufsize-1) OF byte↲
10.1    FUNCTION  bufcount(VAR stack: reference): 0..maxint↲
3.8     FUNCTION  bufsize(VAR r: reference): 0..maxint↲
3.8     FUNCTION  bufsize(VAR ch: chain: 0..maxint↲
3.5     FUNCTION  byt(v:integer): byte↲
3.8     FUNCTION  bytecount(VAR r: reference): 0..maxint↲
3.8     FUNCTION  bytecount(VAR ch: chain): 0..maxint↲
10.2    PROCEDURE chaindown(VAR ch: chain)↲
10.2    PROCEDURE chainextract(VAR ch: chain; VAR ref: reference)↲
10.2    PROCEDURE chaininsert(VAR ch: chain; VAR ref: reference)↲
10.2    FUNCTION  chainlength(VAR ch: chain): 0..maxint↲
10.2    PROCEDURE chainreset(VAR ch: chain)↲
10.2    PROCEDURE chainstart(VAR ch: chain)↲
10.2    PROCEDURE chainup(VAR ch: chain)↲
3.4.2   FUNCTION  chr(n: 0..255): char↲
11.1.2  PROCEDURE closeport(VAR p: port)↲
11.3.1  PROCEDURE connect(VAR p: port; index: 1..maxint;↲
 ╞	╞	╞	VAR compl, disc: reference;↲
  ╞	╞	  ╞	INSPECT remote_name: string;↲
╞	╞	╞	service: conn_service)↲
11.3.1  TYPE╞	    conn_service= (cs_normal, cs_high)↲
┆8c┆┆83┆┆c8┆↓
┆a1┆section kind╞	╞	definition┆05┆↲
9.1     TYPE      create_result= (create_ok, no_memory, ...)↲
11.4    FUNCTION  creditcount(VAR r: referenc): 0..maxint↲
5.9     TYPE      dataarea(offset, top: 0..maxint) =↲
╞	╞	╞	PACKED ARRAY(offset..top-1) OF byte↲
3.5     PROCEDURE dec(VAR v: mtype)↲
9.2.2   PROCEDURE delay(no_of_msecs: 0..maxint)↲
11.3.1  PROCEDURE disconnect(VAR p: port;↲
╞	╞	╞	     index: 1..maxint)↲
3.8     FUNCTION  eventkind(VAR r: reference): event_type↲
3.8     FUNCTION  eventkind(VAR ch: chain): event_type↲
3.8     TYPE      event_type= (not_event, message_event,↲
╞	╞	    ╞	       answer_event, process_removed,↲
╞	╞	╞	       port_closed, disconnected,↲
╞	╞	╞	       letter_sent, letter_arrived,↲
╞	╞	╞	       local_connect, remote_connect,↲
╞	╞	╞	       reset_indication, reset_completion,↲
╞	╞	╞	       credit, data_sent, data_arrived,↲
╞	╞	╞	       data_overrun, dummy_letter,↲
╞	╞	╞	       dummy_lcnct, dummy_rcnct,↲
╞	╞	╞	       dummy_rindic, dummy_rcmpl,↲
╞	╞	╞	       dummy_credit, dummy_sent,↲
╞	╞	╞	       dummy_arrived)↲
3.8     PROCEDURE getbuf(VAR p: pool;↲
╞	╞	╞	 VAR ra: mailbox, VAR r: reference)↲
9.2.2   FUNCTION  getbufdelay(VAR p: pool; VAR ra: mailbox;↲
╞	╞	╞	      VAR r: reference;↲
╞	╞	╞	      no_of_msecs: 0..maxint): wait_result↲
11.3.1  PROCEDURE getconnection(VAR p: port; index: 1..maxint;↲
╞	╞	╞	 VAR compl, disc: reference)↲
11.3.2  PROCEDURE getcredit(VAR p: port; index: 1..maxint;↲
╞	╞	╞	    VAR credbuf: reference)↲
11.3.2  PROCEDURE getreset(VAR p: port; index: 1..maxint;↲
╞	╞	╞	   VAR indic: reference)↲
3.8     FUNCTION  hometest(VAR p: pool;↲
╞	╞	╞	   VAR ref: reference): boolean↲
3.5     PROCEDURE inc(VAR v: mtype)↲
11.4    FUNCTION  index(VAR r: reference): 0..maxint↲

════════════════════════════════════════════════════════════════════════
↓
┆a1┆section kind╞	╞	definition┆05┆↲
3.8     FUNCTION  initpool(VAR p: pool;↲
╞	╞	╞	   no_of_bufs, bufsize: 0..maxint↲
╞	╞	╞	   mem: mem_type): 0..maxint↲
3.5     FUNCTION  int(v:mtype): integer↲
9.1     TYPE      link_result= (link_ok, already_linked,↲
╞	╞	╞	        external_not_found, ...)↲
9.2.1   FUNCTION  locked(VAR mbx: mailbox): boolean↲
11.5    FUNCTION  maxconnections: 0..maxint↲
3.4.3   CONST     maxint↲
11.5    FUNCTION  maxlettersize: 0..maxint↲
3.8     TYPE      mem_type= (...)↲
3.4.3   CONST     minint↲
3.7     PROCEDURE new(VAR ptr: ptrtype)↲
3.7     FUNCTION  nil(VAR ptr: ptrtype): boolean↲
3.8     FUNCTION  nil(VAR pr: process): boolean↲
3.8     FUNCTION  nil(VAR ref: reference): boolean↲
3.8     FUNCTION  offset(VAR r: reference): 0..maxint↲
3.8     FUNCTION  offset(VAR ch: chain): 0..maxint↲
9.2.1   FUNCTION  open(VAR mbx: mailbox): boolean↲
11.1    PROCEDURE openport(VAR p: port; VAR closebuf: reference;↲
╞	╞	╞	 INSPECT name: string; scope: scope_type;↲
╞	╞	╞	 no_of_cons: 0..maxint; rcv_all: boolean)↲
3.4     FUNCTION  ord(v: otype): integer↲
9.2.1   FUNCTION  passive(VAR mbx: mailbox): boolean↲
10.1    PROCEDURE pop(VAR stack_handle, popped_buf: reference)↲
3.4     FUNCTION  pred(v: otype): otype↲
10.1    PROCEDURE push(VAR stack_handle, new_top: reference)↲
3.8     PROCEDURE putbuf(VAR r: reference)↲
11.4    FUNCTION  reason(VAR r: reference): reason_type↲
11.4    TYPE      reason_type= (reason_ok, reason_name,↲
╞	╞	╞	        reason_ressource, reason_closed,↲
╞	╞	╞	        reason_network)↲
11.3.2  PROCEDURE receive(VAR p: port; index: 1..maxint↲
╞	╞	╞	  VAR databuf: reference)↲
11.3.2  PROCEDURE receiveall(VAR p: port; VAR databuf: reference)↲
11.2    PROCEDURE receiveletter(VAR p: port;↲
╞	╞	╞	        VAR databuf: reference)↲
3.8     FUNCTION  releasepool(VAR p: pool;↲
╞	╞	╞	      no_of_bufs: 1..maxint): 0..maxint↲
┆8c┆┆83┆┆e0┆↓
┆a1┆section kind╞	╞	definition┆05┆↲
9.1     PROCEDURE remove(VAR pr: process)↲
11.3.2  PROCEDURE reset(VAR p: port; index: 1..maxint;↲
╞	╞	╞	VAR compl: reference)↲
3.8     PROCEDURE resetevent(VAR r: reference)↲
3.8     PROCEDURE resetevent(VAR ch: chain)↲
9.1     PROCEDURE resume(VAR pr: process)↲
9.2.2   PROCEDURE return(VAR ref: reference)↲
11.1    TYPE      scope_type= (anonymous, local,↲
╞	╞	╞	       regional, global)↲
11.3.2  PROCEDURE send(VAR p: port; index: 1..maxint;↲
╞	╞	         VAR databuf: reference)↲
11.2    PROCEDURE sendletter(INSPECT destination: string;↲
╞	╞	╞	     VAR databuf: reference)↲
3.8     PROCEDURE setbytecount(VAR r: reference; val: 0..maxint)↲
3.8     PROCEDURE setbytecount(VAR ch: chain; val: 0..maxint)↲
3.8     PROCEDURE setoffset(VAR r: reference; val: 0..maxint)↲
3.8     PROCEDURE setoffset(VAR ch: chain; val: 0..maxint)↲
3.8     PROCEDURE settop(VAR r: reference; val: 0..maxint)↲
3.8     PROCEDURE settop(VAR ch: chain; val: 0..maxint)↲
3.8     PROCEDURE setu1(VAR r: reference; b: 0..255)↲
3.8     PROCEDURE setu1(VAR ch: chain; b: 0.255)↲
3.8     PROCEDURE setu2(VAR r: reference; b: 0..255)↲
3.8     PROCEDURE setu2(VAR ch: chain; b: 0..255)↲
3.8     PROCEDURE setu3(VAR r: reference; b: 0..255)↲
3.8     PROCEDURE setu3(VAR ch: chain; b: 0..255)↲
3.8     PROCEDURE setu4(VAR r: reference; b: 0..255)↲
3.8     PROCEDURE setu4(VAR ch: chain; b: 0..255)↲
9.2.2   PROCEDURE signal(VAR mbx: mailbox; VAR ref: reference)↲
10.1    FUNCTION  stackdepth(VAR stack: reference): 0..maxint↲
9.1     PROCEDURE stop(VAR pr: process)↲
3.9.4   TYPE      string(length: 0..255)=↲
╞	╞	╞	╞	 ARRAY(1..length) OF char↲
3.4     FUNCTION  succ(v: otype): otype↲
3.8     FUNCTION  top(VAR r: reference; 0..maxint)↲
3.8     FUNCTION  top(VAR ch: chain; 0..maxint)↲
7.1     PROCEDURE trace(fault: integer)↲
9.1     TYPE      unlink_result= (unlink_ok, no_program_linked,↲
╞	╞	╞	╞	existing_incarnations, ...)↲
┆8c┆┆83┆┆d4┆↓
┆a1┆section kind╞	╞	definition┆05┆↲
3.8     FUNCTION  u1(VAR r: reference): 0..255↲
3.8     FUNCTION  u1(VAR ch: chain): 0..255↲
3.8     FUNCTION  u2(VAR r: reference): 0..255↲
3.8     FUNCTION  u2(VAR ch: chain): 0..255↲
3.8     FUNCTION  u3(VAR r: reference): 0..255↲
3.8     FUNCTION  u3(VAR ch: chain): 0..255↲
3.8     FUNCTION  u4(VAR r: reference): 0..255↲
3.8     FUNCTION  u4(VAR ch: chain): 0..255↲
9.2.2   PROCEDURE wait(VAR mbx: mailbox; VAR ref: reference)↲
9.2.2   FUNCTION  waitdelay(VAR mbx: mailbox; VAR ref: reference;↲
╞	╞	╞	    no_of_msecs: 0..maxint): wait_result↲
9.2.2   TYPE      wait_result= (a_buffer, a_delay)↲
3.5     FUNCTION  wrd(v: integer): word↲
↲
↲
┆b0┆┆a1┆C.2 Language Intrinsic Types↲
↲
┆a1┆section╞	name↲
3.4.1╞	boolean↲
3.5╞	╞	byte↲
3.8, 10.2╞	chain↲
3.4.2╞	char↲
3.4.3╞	integer↲
3.8╞	╞	mailbox↲
3.8╞	╞	pool↲
3.8, 11╞	port↲
3.8, 9.1╞	process↲
3.8╞	╞	reference↲
3.5╞	╞	word↲
↲
↲

════════════════════════════════════════════════════════════════════════
↓
┆b0┆┆a1┆C.3 Language Intrinsic Pseudo-function↲
↲
┆a1┆section╞	description↲
9.1╞	╞	create(INSPECT inc_name: string; program call;↲
╞	╞	    VAR pr: process; size: 0..maxint;↲
╞	╞	╞	  priority: prio_type): create_result↲
9.1╞	╞	link(INSPECT name: string;↲
╞	╞	     VAR prog: program): link_result↲
3.2╞	╞	typesize(type_name): 0..maxint↲
3.12.2╞	varsize(variable_name): 0..maxint↲
9.1╞	╞	unlink(VAR prog: program): unlink_result↲
↲
┆1a┆┆1a┆╞	╞	╞	VAR compl: reference)↲

Full view