Report 82
Report 82
Institute of Informatics
Uniwersity of Warsaw
Report
on the Loglan 82
Programming Language
by
Salwicki
1 http://creativecommons.org/licenses/by-sa/3.0/
Contents
Preface vii
0.1 Thirty years later . . . . . . . . . . . . . . . . . . . . . . . . . . . vii
0.2 Why Loglan? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . vii
1 Introduction 1
2 Basic characteristics 7
2.1 Control structure . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.2 Block structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.3 Procedures and functions . . . . . . . . . . . . . . . . . . . . . . 11
2.4 Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.5 Inheritance alias Prexing . . . . . . . . . . . . . . . . . . . . . . 12
2.6 Object deallocator . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.7 Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.8 Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.8.1 Variable parameters . . . . . . . . . . . . . . . . . . . . . 16
2.8.2 Procedure and function parameters . . . . . . . . . . . . . 16
2.9 Coroutines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.10 Processes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.11 Other important features . . . . . . . . . . . . . . . . . . . . . . 18
5 Declarations 27
5.1 Constant declaration . . . . . . . . . . . . . . . . . . . . . . . . . 27
5.2 Variable declaration . . . . . . . . . . . . . . . . . . . . . . . . . 28
5.3 Unit declaration . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
5.3.1 Class declaration (introduction) . . . . . . . . . . . . . . . 29
5.3.2 Subprogram declaration (introduction) . . . . . . . . . . . 29
5.3.3 Block . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
5.3.4 Inheritance or Prexing . . . . . . . . . . . . . . . . . . . 31
iii
iv CONTENTS
6 Visibility rules 37
6.1 Unit attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
6.1.1 Hidden attributes . . . . . . . . . . . . . . . . . . . . . . . 38
6.1.2 Taken attributes . . . . . . . . . . . . . . . . . . . . . . . 38
6.1.3 Legal and illegal identiers . . . . . . . . . . . . . . . . . 38
6.1.4 Close attributes . . . . . . . . . . . . . . . . . . . . . . . . 39
6.2 Static location . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
6.3 Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
6.3.1 Virtual attributes . . . . . . . . . . . . . . . . . . . . . . . 41
6.3.2 Valuation of virtuals . . . . . . . . . . . . . . . . . . . . . 43
6.4 Dynamic location . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
7 Consistency of types 47
8 Expressions 51
8.1 Constant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
8.2 Variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
8.2.1 Simple variable . . . . . . . . . . . . . . . . . . . . . . . . 52
8.2.2 Subscripted variable . . . . . . . . . . . . . . . . . . . . . 53
8.2.3 Dotted variable . . . . . . . . . . . . . . . . . . . . . . . . 53
8.2.4 System variable: result . . . . . . . . . . . . . . . . . . . . 54
8.3 Arithmetic expression . . . . . . . . . . . . . . . . . . . . . . . . 54
8.4 Boolean expression . . . . . . . . . . . . . . . . . . . . . . . . . . 56
8.5 Character expression . . . . . . . . . . . . . . . . . . . . . . . . . 60
8.6 String expression . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
8.7 Object expression . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
9 Sequential statements. 63
9.1 Sequential primitive statements . . . . . . . . . . . . . . . . . . . 63
9.1.1 Evaluation statement . . . . . . . . . . . . . . . . . . . . 64
9.1.2 Conguration statement . . . . . . . . . . . . . . . . . . . 66
9.1.3 Simple control statement . . . . . . . . . . . . . . . . . . 72
9.1.4 Coroutine statement . . . . . . . . . . . . . . . . . . . . . 74
9.2 Compound statements . . . . . . . . . . . . . . . . . . . . . . . . 75
9.2.1 Conditional statement . . . . . . . . . . . . . . . . . . . . 75
9.2.2 Case statement . . . . . . . . . . . . . . . . . . . . . . . . 76
9.2.3 Iteration statement . . . . . . . . . . . . . . . . . . . . . . 77
10 Exception handling 85
10.1 Signal specication . . . . . . . . . . . . . . . . . . . . . . . . . . 85
10.2 Signal handlers . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
10.3 Signal raising . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
10.4 Handler execution . . . . . . . . . . . . . . . . . . . . . . . . . . 89
10.5 System signals . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
11 Processes 93
CONTENTS v
12 File processing 97
12.1 External and internal les . . . . . . . . . . . . . . . . . . . . . . 97
12.2 File generation and deallocation . . . . . . . . . . . . . . . . . . . 97
12.3 Binary input-output . . . . . . . . . . . . . . . . . . . . . . . . . 99
12.4 Other predened operations . . . . . . . . . . . . . . . . . . . . . 99
12.5 Text input-output . . . . . . . . . . . . . . . . . . . . . . . . . . 100
12.6 Example of high-level le processing . . . . . . . . . . . . . . . . 102
vi CONTENTS
Preface
• Teachers Loglan'82 is a good choice if you wish to present all the meth-
ods and tools of object programming without passing from one language to
another for presenting the complete set of object programming constructs,
• how to dene inheritance when the extended class is not a brother of the
present class?
vii
viii PREFACE
Introduction
LOGLAN-82 1 is a universal programming language designed at the Institute
of Informatics, University of Warsaw. The shortest, informal characterization
of the language would read as follows. LOGLAN-82 belongs to the Algol family
of programming languages. Its syntax, however, is patterned upon Pascal's [5].
Many ideas are borrowed from SIMULA-67 [3]. The language includes also some
modern facilities such as concurrency and exception handling.
The characteristic programming constructs and facilities of the language are
as follows:
• encapsulation techniques,
• exception handling,
• le processing.
1
2 CHAPTER 1. INTRODUCTION
LOGLAN-82 history
In the early seventies the Institute of Mathematical Machines "MERA" (with
two members of the present team of authors) and the Institute of Informatics
of Warsaw University initiated the design of a new high level programming lan-
guage2 . There were two main inspirations for taking up this research. First, the
awareness that the SIMULA 67 programming language was a substantial con-
tribution to the software methodology, and second, that the fast development of
multiprocessor hardware will change the software practice. We began our work
with analytical studies, seminars and lectures dealing with the basic constructs
and features of the known programming languages. This helped us to establish
the goals a new programming language should reach. By then, however, we
decided that the design of the programming language would be a component of
a broader software project, called LOGLAN.
There is no doubt that the environment in which our investigations have been
carried out has shed a new light on these goals. In particular, the experience
accumulated by a big part of our team in the eld of Algorithmic Logic [4][15]
inuenced the form of the solutions accepted.
The rst step of our work was nished in 1977 with the report on the
LOGLAN programming language [6][12]. The report provided a general out-
line of a universal programming language. Among its most important features
let us mention a new approach to arrays, assignments, parameter transmission
and parallel computations. This version was not implemented. It constituted
the base for the agreement between the University of Warsaw and the State
Industrial Trust MERA, signed a year later.
A careful analysis of the constructs suggested in the primary project preceded
an actual implementation. With the intention of attaining this, the interpreter
of the language was designed. At that stage a number of important modications
were introduced to the proposed outline. They resulted from experiments with
the interpreter which proved the usefulness of some constructs and the useless-
ness of some others. At the next stage of research the language was implemented
on the original Polish two-processor minicomputer MERA 400. The design was
restricted in several points because of the implementation constraints. Some
constructs were rejected, the decision concerning some others was put o until
a more elaborate analysis was carried out. The experience of the team in the
eld of abstract data types and computational complexity helped us to solve
one of the most fundamental implementation problems - a proper structure for
secure and fast storage management. In consequence, the language is furnished
with a programmed deallocator which allows the user to design the best strat-
egy of storage management at run time. The implementation of unrestricted
prexing needed a completely new approach. The well-known mechanisms like
Dijkstra's display do not allow us to release the SIMULA restrictions (the most
important forbids the use prexing at dierent levels of unit nesting). Such a so-
lution was found and the LOGLAN-82 users may apply prexing at an arbitrary
level of unit nesting.
Of the results we have obtained so far let us mention paper [2][1], which
deals with the principles of an ecient implementation of programming lan-
guages with prexing at many levels. The paper introduces the generalized
• tasking dialect similar to ADA's tasks, cf.[11], with the main notions: task,
accept, select, rendez-vous.
30 years later
3 From the perspective it is easy to observe two facts:
Acknowledgments
We wish to express our gratitude to all institutions and persons who supported
us materially or morally. Thanks are due to the State Industrial Trust "MERA"
and to its deputy director professor A.Janicki for the arrangements that enabled
us to realize the LOGLAN-82 project. The LOGLAN-82 team wishes to thank
all colleagues in Warsaw for criticism and helpful remarks. This report has
been carefully read by a number of people, including J.Deminet, F.Kluzniak,
A.Janicki, J.Rudzi«ski, W.M.Turski. Their critical comments helped us to avoid
numerous mistakes.
3 one
6 CHAPTER 1. INTRODUCTION
Chapter 2
if boolean expression
then
sequence of statements
else
sequence of statements
fi
The semantics of a conditional statement is standard. The keyword allows
us to nest conditional statements without the appearence of the "dangling else"
ambiguity. The "else" part in a conditional statement may be omitted:
if boolean expression
then
sequence of statements
fi
For the execution of a conditional statement with the orif list the specied
conditions B1, ..., Bk are evaluated in succession, until the rst one evaluates
7
8 CHAPTER 2. BASIC CHARACTERISTICS
to true. Then the rest of the sequence is abandoned and the "then" part is
executed. If none of the conditions evaluates to true, the "else" part is exe-
cuted (if any). The orif construction provides a good method for a short circuit
technique, since the boolean expression controling the conditional statement
execution need not be evaluated till the end.
Similarly, a conditional statement with the andif list has the form:
if B1 andif ...andif Bk
then
sequence of statements
else
sequence of statements
fi
For the execution of this kind of statement the conditions B1, ..., Bk are
evaluated in succession until the rst one evaluates to false. Then the "else"
part is executed (if any). Otherwise the "then" part is executed.
The basic form of an iteration statement in LOGLAN-82 is the following:
do
sequence of statements
od;
To terminate the iteration statement one can use the simple control state-
ment exit, which has the following syntactic form:
The type of the controlled variable j must be discrete. The value of this
variable in the case of the for statement with to is increased, and in the case of
the for statement with downto is decreased. The discrete range begins with the
value of A1 and changes with the step equal to the value of A2. The execution
of the for statement with to terminates when the value of j becomes for the rst
time greater than A3 (with downto when the value of j becomes for the rst
2.2. BLOCK STRUCTURE 9
time less than A3). The values of the expressions A1, A2, A3 are evaluated
once, upon entry to the iteration statement. The default value of A2 is equal
to 1 (when the keyword step and A2 are omitted).
An iteration statement with the while condition has the form:
do
if not boolean expression then exit fi;
sequence of statements
od;
To enhance the users's comfort, the simple statement repeat is provided. It
may appear in an iteration statement and causes the current iteration to be
nished and the next one to be continued (something like jump to CONTINUE
in Fortran's DO statement). In general, this statement has the form:
case A
when Q1 : G1
when Q2 : G2
...
when Qk : Gk
others G
esac
where A is an arithmetic expression, Q1, ..., Qk are constants and G1, ..., Gk
are sequences of statements. A case statement selects for execution a sequence
Gj where the value of A equals Qj. The choice others covers all values (possibly
none) not given in the previous choices.
block
list of declarations
begin
sequence of statements
end
10 CHAPTER 2. BASIC CHARACTERISTICS
The list of declarations denes some syntactic entities, e.g. constants, vari-
ables, procedures, functions etc., whose scope is that block. The syntactic enti-
ties occurring in the sequence of statements are identied by means of identiers
which are introduced in the declaration lists. For every identier occurrence it
must be possible to identify the corresponding syntactic entity. This kind of cor-
respondence between occurrences of identiers and syntactic entities is necessary
to dene the semantics of a block statement. The block statement semantics
may be described as follows.
When a block is entered, a dynamic instance of the block is generated. In a
computer, a block instance takes the form of a memory frame containing syn-
tactic entities declared in that block. All local syntactic entities of an instance
will be called its attributes .
The frame of a block instance may be viewed as a box (with displayed
attributes when necessary).
------------------------
| attribute k |
-----------------------|
| ... |
-----------------------|
| attrbute l |
------------------------
a block instance
A block is a statement, and so other blocks may occur in its sequence of
statement (i.e., blocks may be nested). Observe, that the occurrences of iden-
tiers in an inner block need not be local. They can refer to entities declared
in the outer block. For a non-local occurrence of identier, the corresponding
attribute of a non-local instance should be identied. That identication is
possible thanks to an auxiliary notion of a syntactic father.
Consider the following block structure:
---------------------
| block outer |
| |
| ------------- |
| | block | |
| | inner | |
| ------------- |
| |
---------------------
When the statements of block2 are executed, the following two dynamic
block instances are created:
------------- -----------------
| DI{inner} | ==================> | DI{outer} |
------------ SL -----------------
2.3. PROCEDURES AND FUNCTIONS 11
Here O[1] is an instance of the block1, and O[2] is an instance of the block2.
The instance O[1] is called the syntactic father of O[2] (or alternatively the
instance O[2] is syntactically linked by the SL-link with the instance O[1]).
During a program's execution the sequence of syntactic fathers determined by
an active instance forms a chain, called an SL-chain. The instances forming the
SL-chain correspond to the consequtive enclosing units of the program, starting
from the active one and ending on the main block. Thus, this chain allows us
to identify all non-local occurrences of identiers.
A block statement terminates when the control reaches its nal end, and
then its instance is automatically deallocated.
A procedure is a named syntactic unit which may be invoked only via its
identier by means of a call statement:
call name (actual parameters);
(Procedures dier from blocks also in that they can have parameters, but
this question will be discussed later.)
When a procedure is called, its instance is created, as in the case of a block.
All local attributes are allocated in the new frame. A syntactic father of such
a newly generated instance is dened as usual, and allows us to identify all
non-local attributes.
A procedure call is terminated when the control reaches return statement or
the nal end. Then the control returns to the instance where the procedure was
called. That instance is referred to by another system pointer (DL-link).
After the termination of a procedure call there is no syntactic means to
access its local attributes, hence its instance is automatically deallocated.
Functions dier from procedures only in that they return a value and are
invoked in the expressions.
2.4 Classes
To meet the need for permanent data structures LOGLAN-82 introduces the
notion of class (cf [3]). Class is declared in a similar way to procedure. It is
named and may have parameters:
12 CHAPTER 2. BASIC CHARACTERISTICS
var X: M;
and may point to any object of class M, for instance, the statement:
X:=new M(...)
generates an object O of class M and assigns its address (reference) to X.
The default value of any reference variable is none, which denotes ctitious non-
existing object. What is left behind is a structure of attributes which can be
accessed by means of dot-notation. These accessible attributes are either formal
parameters or local entities. If X is a reference variable of type M and W is an
attribute of class M, then the remote access to the attribute W has the form:
X.W
The above remote access is correct if X points to an object O of class M.
Otherwise a run time error is raised (for instance when the value of X is none).
unit M: class;
list of declarations of M
begin
sequence of statements of M
end ;
2.5. INHERITANCE ALIAS PREFIXING 13
unit N: M class
list of declarations of N
begin
sequence of statements of N
end ;
---------------
| |
| ... | M-attributes
| |
--------------- - - - - - -
| |
| |
| ... | N-attributes
| |
---------------
object of N
X:=new N ,
begin
...
end STACK;
Any class prexed by STACK inherits the operations on stack. For instance,
in a class declaration
the function pop and the procedure push may be used as any other local
attribute.
A class may also be used to prex blocks, procedures and functions. An
instance of a prexed block is a compound object and is created upon entry to
the block and deallocated after its termination, as in the case of a simple block.
Similarly, an instance of a prexed procedure (function) is a compound object
which is created when a procedure (function) is called and deallocated after its
termination.
kill(X)
deallocator provides full security, i.e., the attempt to access the deallocated
object O is checked and results in a run-time error. For example,
X:=none; X.W:=Z;
The system of storage management is arranged in such a way that the frames
of killed objects may be immediately reused without the necessity of calling the
garbage collector, i.e., the relocation is performed automatically.
2.7 Arrays
LOGLAN-82's array is a kind of a class with indices instead of identiers select-
ing the attributes. A variable of an array type is a reference variable pointing
to an object which contains components of a one-dimensional array. The com-
ponents of such an array may also point to one-dimensional arrays and so forth,
hence multi-dimensional arrays may be generated as well.
The declaration of a variable Y of array type has the following form:
array Y dim (l : u)
where l, u are arithmetic expressions determining the lower and upper bounds
of the rst index. The object O of an array is generated and the reference to O
is assigned to Y.
If Y is declared as a two-dimensional array, then one can generate a two-
dimensional array by means of the statements
for i:=l to u
do
array Y(i) dim (li:ui)
od;
where the shape of each row is determined by the bounds li, ui. Hence
triangular, tridiagonal, streaked arrays, etc. may be generated. Moreover, the
assignment statements allow us to interchange array references that are of the
same dimension and the same type, e.g. Y(i):=Y(j). In consequence, the user
may operate on array slices. The default value of any array variable is none, as
in the case of a reference variable.
16 CHAPTER 2. BASIC CHARACTERISTICS
2.8 Parameters
In LOGLAN-82 there are four categories of parameters: variable parameters,
procedure parameters, function parameters and type parameters.
2.9 Coroutines
Notion of coroutine is an extension of the class notion. A coroutine object is
an object whose sequence of statements can be suspended and reactivated in
the programmed manner. The generation of a coroutine object terminates with
the execution of the return statement (then the control is passed to the caller
as in the case of classes). A coroutine object after the execution of the return
statement is suspended. A suspended coroutine object may be reactivated with
the help of the attach statement:
attach(X)
2.10 Processes
The concept of process in LOGLAN-82 is a natural extension of coroutine.
Coroutines are units which once generated may operate independently, each one
treated as a separate process. For coroutines, however, an essential assumption
is established; namely, when one coroutine object is activated, the active one
must be suspended. When processes are used, the activation of a new process
does not require the active one to be suspended. Thus during a program's
execution many processes may be active simultaneously. Their statements are
computed in parallel. There are two operations, stop and resume, which concern
the control of processes.
18 CHAPTER 2. BASIC CHARACTERISTICS
that deal with high-level le operations are also given. (For details see 13).
20 CHAPTER 2. BASIC CHARACTERISTICS
Chapter 3
a b c d e f g h i j k l m n o p q r s t u v w x y z
(b) 10 digits:
0 1 2 3 4 5 6 7 8 9
# $ ? % ^
(lower case letters are equivalent to the corresponding upper case ones.)
A nite sequence of characters is called a word. The words called identiers
have a special meaning. They are composed of letters, digits, and underscores
and start with a letter:
<identifier>:
21
22 CHAPTER 3. LEXICAL AND TEXTUAL STRUCTURE
The lexical entities are identiers, numbers, strings and delimiters. The
delimiters from the basic character set are:
, ; = / + - * > < . ( ) :
and the compound symbols are :
Types
A type T determines a set |T| of values and a family of operations applicable to
the elements of the set. Three kinds of types are distinguished: primitive types,
system types and compound types. Variables may be declared to be of type T.
Depending on the kind of type T we have to distinguish two cases.
a) T is a primitive type. The value assigned to a variable Y of type T must
belong to the set |T|.
b) T is a compound or system type. The value assigned to a variable Y of
type T must be a reference pointing to an object in the set |T| (for the notion
of reference cf 4.3. and 6.3.)
Syntax .
<type identifier>:
23
24 CHAPTER 4. TYPES
| |
|--> boolean -->|
| |
|-> character -->|
| |
|---> string -->|
Semantics.
A primitive type determines a nite set of values which can be eectively
represented in a computer memory:
- unit T : coroutine
- unit T : process
- unit T : S class
- unit T : process
- unit T : S class
where |S| is already a subset of the set |process|.
The user may declare a variable of coroutine (process) type, e.g. of the form
var X : coroutine;
(var X : process;)
(arrayof)i T =
| {z }
i times
T, for i = 0
<class identifier>:
Semantics
A formal type is a formal parameter of a unit and can be treated as the
name of an abstract data structure without any attribute. The corresponding
actual type must be a system type or a compound type. The set of objects of
the formal type T from a dynamic object O is equal to the set of objects of the
actual type which occurs in the actual parameter list of O.
Chapter 5
Declarations
Every identier which is to be used in a program must be dened. System
identiers are pre-dened, other identiers are pre-compiled, (see 12.) or they
are dened by means of a declaration or description in the formal parameter
list. LOGLAN-82 is not strongly typed in the sense that sometimes the type
of variable and function value cannot be determined at compilation time. The
user may balance the generality and convenience given by the formal types
mechanism and the risk of reduced eciency of his program execution. The
compiler option, however, allows us to supress the run time checking with respect
to the type compatibility.
Syntax .
<declaration>:
27
28 CHAPTER 5. DECLARATIONS
Semantics.
The expression dening the constant must be determinable at compilation
time. The type and the value of the constant is given by its declaration. They
are always primitive.
Example.
<specification list>:
<identifier list>:
Semantics.
A variable is of a type given in a variable declaration. A declaration is
elaborated at the instant of generation of a unit object which contains that
declaration. An elaboration determines an initial value for every variable. This
value depends on the type identier :
integer - 0
real - 0.0
boolean - False
semaphore - open
character and string - defined in concrete implementation
any compound and system type - none
<class declaration>:
<prefix>:
| ^ | ^ |
|----------| |------------| |
|
<-------------------------------------------------------|
| |
|--> <formal parameter list> -------------------------->|
|
<------------------------- ; ---------------------|
|
|--> <subprogram body> ------------------------------>
| ^
|-> <procedure identifier>->|
<procedure identifier> :
<function declaration>:
<function identifier>:
Class (function, procedure) identier may optionally follow the end symbol
(and if present must match the unit name).
Example.
unit Euclid: function(n, m:integer):integer;
var k:integer;
begin
do
5.3. UNIT DECLARATION 31
k:=n mod m;
if k=0 then result:=m; return fi;
n:=m; m:=k;
od;
end Euclid;
5.3.3 Block
In order to complete the description of LOGLAN-82 units the block syntax is
given here, however the occurrence of a block results in the execution of its
statements - see 9.1.2..
Syntax .
<block>:
--> pref --> <prefix> ---> <actual parameter list> ---> block ---->
| ^ ^ |
|-------------------->|--------------------------->| |
|
|<------------------------------------------|
|
|--> <subprogram body>------>
Example.
block
var a, b, c, p, S:real;
begin
read(a, b, c);
p:=(a+b+c)/2;
S:=sqrt(p*(p-a)*(p-b)*(p-c));
write(S)
end
<input parameters>:
<output parameters>:
<inout parameters>:
<type parameters>:
<procedure parameter>:
<function parameter>:
Semantics.
34 CHAPTER 5. DECLARATIONS
<subprogram body>:
<inheritance list>:
<protection list>:
|------------------------------------>|
| |
--------> <declaration> -------> ; ---------------->
^ |
|<------------------------------|
<statement list>:
Semantics.
In a unit body, a sequence of statements (if any) starts from the begin
symbol. Declarations/statements are separated by semicolons. An execution of
the unit body begins at the time of the generation of an object (of that unit),
see 9.1.2.. A declaration of a unit M is restricted at several points :
Restrictions
(i) The least (textual) unit containing an occurrence of a control statement
inner (see 9.1.3.) must be a generalized class. An inner statement may occur in
the class body at the most once. If it does not occur explicitly then the body
of unit M is assumed to contain the inner statement as the last one (preceding
the end symbol).
(ii) All identiers dened in the body of unit M are dierent.
(iii) The input/output formal parameters of unit M cannot be of a type
declared in unit M.
36 CHAPTER 5. DECLARATIONS
37
38 CHAPTER 6. VISIBILITY RULES
unit N : class;
hidden x, y, z;
var x, y, z:integer;
...
end N;
All identiers dened in a unit are legal in that unit. In particular, all
identiers declared in a non-prexed unit are legal.
Now let M be a unit, N its prex and W an identier not dened in M. Then
W is a legal identier corresponding to an attribute of M i
- W is legal in N - W does not occur in the hidden list in N - W occurs in
the taken list in M or this list is absent
All identiers specied in every context in a unit must be legal in that unit.
All identiers specied in the taken list must be legal in the prex.
An identier is illegal in a unit i it denotes an attribute of the unit (ac-
cording to 6.1) and that attribute is not legal.
block
var v:A;
unit A: class;
hidden z;
close x;
var x, z:real, y:A;
end B;
begin
end A;
40 CHAPTER 6. VISIBILITY RULES
begin (* outside A *)
block
unit M: class; var X ... end M;
unit N: M class; var X ... end N;
begin
pref N block (* P *)
var Y : ...;
6.3. OBJECTS 41
unit R: class;
... X ... Y ...
end R;
begin
new R;
...
pref N block (* S *)
var Y : ...,
unit T: R class;
... X ... Y ...
end T;
begin
new T;
...
end S;
end P;
end
Here we have
6.3 Objects
An object O of type M with the prex sequence M1, ..., Mk=M (k=>1) is:
- a k-tuple of the form O = (<V1, M1>, ... <Vk, Mk>) where Vi is the
valuation of non-static attributes dened in the unit Mi, - and a unique reference
pointing to this k-tuple.
Since the references are unique, two objects are dierent even if their tuples
are identical.
Now let us dene the valuation of an attribute of object O, depending on
the kind of that attribute:
- the valuation of variables and variable parameters gives their values, - the
valuation of an attribute which is a subprogram is the text of its declaration and
an environment. (The environment is the object containing the declaration of
the subprogram. In the case of a formal subprogram the value is determined by
the actual one (see 9.1.2.). The case of virtuals is discussed below.) - an attribute
which is a type has the value of the form: (arrayof)<j> text of declaration.
P .... F ....
R unit F: <R-body>
T unit F: <T-body>
We have three virtual chains of F with respect to T. One is for F from the
classes M and N:
(F: <M-body>), (F: <N-body>),
The second is for F from the class S:
(F: <S-body>)
And the third one is for F in T:
(F: <T-body>)
Restrictions
(i) All virtual attributes belonging to the same virtual chain must be of the
same kind (either function or procedure),
(i) All the declarations of the virtuals belonging to the same virtual chain
must have formal parameter lists of the same pattern, in particular:
- the lists may use dierent names of formal parameters, but the cor-
respondence between formal types must remain valid,
- the class types of corresponding formal variables or functions must
belong to the same prex sequence,
- the types of variable parameters or formal functions in the ending
of the virtual chain must not be less strongly dened than the types
of the corresponding parameters in the beginning, i.e., a formal or
system type against a statically dened type,
6.3. OBJECTS 43
(2) The following lists are compatible i M and N belong to the same prex
sequence (and both are classes)
.... (type T; Z: T; Z1: M) ....
.... (type P; X: P; Y: N) ....
(3) The following lists are compatible i M denotes a system type (coroutine
or process) or is a formal type
at the beginning: (X: M; Y: real)
at the ending: (X:coroutine; Y:real)
(5) The lists of the function from the beginning of the chain
... function (Z:integer; Z1:P) : M
- the text of the declaration taken from the end of the virtual chain,
44 CHAPTER 6. VISIBILITY RULES
Example 6.3. An object of the class T given in the example 1 from 6.4.1 is of
the following form:
---------------------------------------------
| | |
| F : body F from N | M |
---------------------------------------------
| | |
| F : body F from N | N |
---------------------------------------------
| | |
| | P |
---------------------------------------------
| | |
| F : body F from R | R |
---------------------------------------------
| | |
| F : body F from S | S |
---------------------------------------------
| | |
| F : body F from T | T |
---------------------------------------------
The name "virtual subprogram" is derived from the features of virtual entities,
i.e., in any class a virtual subprogram F with an empty statement list can be
declared and then used as a virtual entity within the body of the class. The
user can assume the results of its execution without knowledge of its internal
structure. He can declare in a subclass a virtual subprogram F again. This
declaration replaces the previous one. So, during the calls of the subprogram F
in the body of the class as well as in the body of the subclass, the subprogram
with the text dened in the subclass will be executed. This replacement is done
only if F is a virtual attribute of the subclass. Otherwise the new declaration
of F covers the virtual attribute of the class.
Abstention from those rules permits us:
(i) to dene the types of the parameters of a virtual subprogram and to check
them already at compilation time,
(ii) to execute the virtual subprogram declared at the beginning of the prex
sequence; its body may be empty, but it is always dened,
(iii) to end the virtual chain and to cover a virtual identier by a redeclaration.
The possibilities (ii) and (iii) can be used in the following case. Let M and N
be system classes of the form :
unit M: class;
unit virtual error: procedure;
(* virtual procedure to be defined in M's subclasses*)
end error;
6.4. DYNAMIC LOCATION 45
begin
...
if B1 then call error fi;
end M;
unit N: M class;
unit virtual error: procedure;
(* the definition of the body of error. It
will be executed during the calls within N
as well as in M *)
end error;
begin
...
if B2 then call error fi;
end N
If the programmer prexes his own units by class M, he can declare his own
virtual procedure error. If he does not intend to signalize any errors, he is
able to use M without a redeclaration. Then if the condition B1 is satised, the
procedure with an empty body will be called, i.e., no statement will be executed.
On the other hand, if the programmer uses N as a prex of his own units, he
can redeclare his own non-virtual procedure error. In consequence, during the
execution of statements of the classes M and N the procedure dened by this
system in the class N will be executed. However during the execution of the
user's units the procedures dened by himself will be executed.
| X | M | | X | M | | | R |
<----- |------|-----| <------- |-----|----| <------ |-------|-----|
| X | N | SL | X | N | SL | | |
|------|-----| |-----|----| | | T |
OP | Y,R | P | OS | Y,T | S | O | | |
-------------- ------------ ---------------
Because SC(X, R)=SC(X, T)=N , we have DC(X, R, O)=DC(X, T, O)=OS.
Since SC(Y, T)=S , we have DC(Y, T, O)=OS. On the other hand SC(Y, R)=P
and DC(Y, R, O)=OP. The syntactic environment of an object is determined
by the SL chain. Its main property is that for each identier occurrence in the
statements of the given object exists its dynamic container in the chain. In
order to dene the dynamic location of identier W occurring in object O of
unit M in a body of unit R (which belongs to the prex sequence of M), the
following steps are performed:
- a static container N=SC(W, R) is dened; - a dynamic container O1=DC(W,
R, O) is dened (in the SL chain of object O, the nearest object O1 is found
such that this object has a "layer" <V, N>); - a valuation V1(W) is found in
the layers <V1, N1> of the object O1 such that N1 is the nearest N's prex.
Chapter 7
Consistency of types
In order to determine the context-sensitive correctness of an assignment state-
ment and parameter transmission it is necessary to introduce the notion of the
static consistency of types. Nevertheless this notion is not sucient to deter-
mine the correctness of the executions of those constructs. Therefore, the notion
of the dynamic consistency of types will be introduced to dene the semantic
correctness of program. The introduced distinction follows from the implemen-
tation constraints; namely, static consistency is veried at compilation time,
dynamic consistency is veried at run time.
• i=j=0 and T and S are one of them a system type and the other a gener-
alized class or system type.
47
48 CHAPTER 7. CONSISTENCY OF TYPES
At run time all formal types are replaced by actual non-formal ones. Therefore,
there is no reason to dene dynamic consistency for formal types. Dynamic
consistency is a subrelation of static consistency. Thus the dynamic consistency
is checked at compilation time, if possible. In other cases the check is made at
run-time. From now on we shall use the following notation:
- for the desription of context properties, an occurrence of an expression E is
considered to be contained in the body of unit M,
- for the desription of semantic properties, an occurrence of an expression E is
considered to be contained in the body of unit M, with respect to an object O
of type M0 such that M pref* M0.
49
8.
50 CHAPTER 7. CONSISTENCY OF TYPES
Chapter 8
Expressions
Expressions are composed of primitive expressions - constants and variables by
means of system operators and functions. They serve as patterns for computing
a certain value. Two kinds of expression properties have to be considered:
context (static) and semantic (dynamic) ones.
Context properties . We consider two context properties of each expres-
sion:
• to be a well-formed formula,
51
52 CHAPTER 8. EXPRESSIONS
8.1 Constant
Syntax.
<constant>:
8.2 Variable
Syntax.
<variable>:
Let E be a variable Z.
Context . The variable Z is a WFF if the static container SC(Z, M) = R
exists. The static type of Z is determined by the declaration of Z and may be a
formal one.
Semantics .
8.2. VARIABLE 53
Let E be an expression of the form Z(A1, ..., Ak), where Z is a simple variable
and A1, ..., Ak are arithmetic expressions.
Context .
Let (arrayof)<i>S denote a static type of Z. The expression Z(A1, ..., Ak) is
a WFF if: - Z and A1, ..., Ak are WFFs, - static types of A1, ..., Ak are integer
or real, - 1<=k<=i. The static type of E is (arrayof)<i-k>S.
Semantics .
The expression E is dened if: - the expression Z(A1, ..., Ak-1) is dened and
its value equals the reference to a non-empty array object O1 with the bounds
l and u, l<=u. - the value of Ak is dened and its truncation l1 satises:
l<=l1<=u.
The dynamic type of E is equal to the static one if S is not formal, otherwise
it is (arrayof)<i-k+j>T where the actual type corresponding to the formal one
is (arrayof)<j>T. The actual type is determined as for a simple variable (see
8.2.1.). The value of E is that of the attribute (l1) of the object O1. The address
of E is the pair: (the reference to O1, attribute (l1)).
The static type of E is the same as the static type of Y. Notice that the
static type of X cannot be a formal type.
Semantics .
The expression E is dened if:
- the expression X is dened, - the value of X is a reference to a non-empty
object O1.
The dynamic type of E is the same as the dynamic type of Y would be if Y
occurred in the object O1. The value of X.Y is that of the attribute Y of the
object O1. The address of X.Y is the address of Y would be if Y occurred in
O1.
<system variable>:
|------------------->|
| |
-----------> <sign> --------> <term> ------->
^ |
8.3. ARITHMETIC EXPRESSION 55
|<--------------------------------|
<sign>:
-----> + ----->
| ^
|-> - -->|
<term>:
<factor>:
<integer>:
<real>:
|-------->|
| |
---> <integer>--> . ---> <integer>----->E --> <sign>--> <integer> -->
| ^ | ^
56 CHAPTER 8. EXPRESSIONS
|------------------>| |---------------------------->|
(function call will be dened in 9.1.2.).
Context and Semantics .
The type of the value of an arithmetic expressionXE "arithmetic expres-
sion" is always equal to its static type. The dynamic type is not to be dened.
The context and semantic properties of arithmetic expressions will be dened
inductively.
Factors.
The type of an integer is integer, the type of a real is real, their values are given
directly. Constant, variable, and function call must be WFFs (in the meaning of
8.1., 8.2 and 9.1.2.), and of type integer or real (in order to create a well-formed
factor). The factor is dened i the variable and the function call are dened.
The context and semantic properties of the factors of the form " abs A1 ", and "
(A2) " are the same as those of arithmetic expressions A1 and A2, respectively.
The value of " abs A1 " is the absolute value of A1.
Terms.
The operators *, /, div, mod are interpreted as multiplication, division, integer
division and remaindering, respectively. The last two operators are dened for
integer arguments only, " A1 div A2 " is equal to the truncation of A1/A2; "
A1 mod A2 " is equal to the remainder of A1/A2. The type of a term of the
form <factor> <operator> <factor> is real if the operator is /, or at least one
of the arguments is of type real. The term " A1/A2 " is dened if the value of
A2 is dierent from 0. The value is dened inductively if Av1 and Av2 are the
values of factor A1 and term A2 respectively, and <W> is an interpretation of
operator W, then the value of a term of the form " A1 W A2 " is Av1 <W>
Av2. If one of the arguments is of type integer and the other is of type real then
for the operators *, / the integer type value is converted into a real type one.
Arithmetic expression.
An arithmetic expression of the form <term> <sign> <term> is of type integer
if both terms are of that type and it is of type real in the opposite case. A value
is dened inductively: if Av1 and Av2 are the values of term A1 and arithmetic
expression A2, respectively, then the value of an expression A1+(-)A2 is Av1+(-
)Av2, the value of +(-)A1 is +(-)Av1. If one of the arguments is of type integer
and the other is of type real, then the integer type value is converted into a real
type one.
<boolean expression>:
<boolean term>:
<boolean factor>:
<boolean primary>:
<relation>:
<boolean constant>:
<arithmetic relation>:
58 CHAPTER 8. EXPRESSIONS
<equality operator>:
----------> = ---------------->
| ^
|------> =/= ------->|
<inequality operator>:
--------------------------------->|
| | | |
< > <= >=
| | | |
|------------------------------->
<character relation>:
<reference relation>:
<object relation>:
8.4. BOOLEAN EXPRESSION 59
<character expression>:
<character constant>:
<symbol>:
<string expression>:
| |
|---> <variable> ------->|
| |
|---> <function call> -->|
<string constant>:
Semantics.
Constant, variable and function call are WFFs if they are of string type. The
quotation mark " in the string constant is written twice "".
Remark The string type is a constant type in the sense that the universe is
dened at compilation time and there are no string operations predened in the
language. However, a standard function may transform a string into an array
of characters. Then the user can treat the array of character as a text type and
can dene any set of suitable text operations.
End of remark
<object expression>:
<object constant>:
<local object>:
Sequential statements.
Sequential statements are patterns for the sequencing of primitive actions.
Syntax .
<sequential statement>:
<primitive statement>:
63
64 CHAPTER 9. SEQUENTIAL STATEMENTS.
9.1.1.
<empty statement>:
--------------------------->
Semantics.
An execution of an empty statement leaves the overall state of computation
not changed.
Syntax.
<assignment statement>:
<variable list>:
Context.
An assignment statement of the form y1, ..., yk:=e is a WFF if:
- the static types T1, ..., Tk of variables y1, ..., yk are statically consistent
with the static type S of the expression E.
9.1. SEQUENTIAL PRIMITIVE STATEMENTS 65
Semantics.
The execution of the statement consists of three steps : prologue, body and
epilogue.
In the prologue the computation of the addresses of variables y1, ..., yk is
performed, i.e.:
- For a dotted variable of the form X.z, the value of the expression X is
computed;
- For a subscripted variable of the form Z(i1, ..., ij) the value of the expression
Z(i1, ..., ij-1) is computed. If Z is of a formal type, then the dynamic type T of
the variable Z is determined. Finally the value of the expression ij is computed.
The above actions are performed from left to right.
During the body the computation of the type and the value of expression E
is performed.
The epilogue checks if the statement is well-dened and assigns the values
to the attributes determined by the addresses evaluated during the prologue.
An assignment is dened, if: - the expressions y1, .., yk, E are dened; - the
dynamic types of y1, .., yk are dened and are dynamically consistent with the
type of the value of E.
The values are assigned from right to left, i.e., at rst the value of E is
assigned to yk (with possible conversion to the type of yk), next the value of yk
is assigned to yk-1 (with appropriate conversion), and so on.
For example, when r is real, n is integer, then:
after r, n:=2.5 we have n=2, r=2.0, after n, r:=2.5 we have r=2.5, n=2.
Remark.
The value of the expression Z computed at prologue may point to a non-
empty object O, but it could be changed to none as a result of the deallocation
of the object O (during the execution of the statement). This will be detected
at epilogue and will result in a run-time error.
End of remark.
An object of a compound type can be simultanously referenced by a number
of variables. If X and Y are the variables of such a type, then after assignment
X:=Y, both variables reference the same object. Hence some side-eects may
occur: the value of an attribute of the object referenced by variable X can be
changed as a result of an access to that object by means of variable Y. In order
to avoid such eects, one can use a copying statement:
X:=copy(Y)
after which both variables reference identical objects but not the very same
one.
Syntax .
<copying statement>:
-> <variable list> -> := -> copy -> ( -> <object expression> -> ) ->
- The copying statement is dened if the value of the right side object ex-
pression E is a reference to a terminated class object (i.e., an object whose all
statements were completed, see 9.1.3). Coroutine or process objects must not
be copied.
- During the epilogue, the copy of the value of the expression E is assigned
(a copy of none is none). 9.1.2.
<configuration statement>:
9.1.2.1.
Allocation statement
Syntax.
<object allocation>:
<function call>:
<procedure call>:
<object generation>:
Context.
We shall start with an allocation of a unit object O, i.e., subprogram call, ob-
ject generation and block statement. The execution of those statements causes
the generation of the new object O. Let Pa1, ..., Pak denote actual parameters,
k>=0, and let X be an object expression. The allocation of an object of unit
M is of one of the following forms:
- for function M: M(Pa1, ..., Pak) or X.M(Pa1, ..., Pak) (a function call must
occur in an expression; it is not allowed as an independent statement);
- for procedure M: call M(Pa1, ..., Pak) or call X.M(Pa1, ..., Pak);
- for class M: new M(Pa1, ..., Pak) or X.new M(Pa1, ..., Pak); (an object
generator may occur in an expression and it is also allowed as an independent
statement).
- for block statement: pref M(Pa1, ..., Pak) block...end or block... end (a
block can be considered as an unnamed unit and a generation of its object is
the result of an occurrence of that block statement).
The allocation of a unit object is a WFF if:
- a unit identier M is visible (in the sense of the rules used for the variables,
see 8.2.), - the actual parameters are WFFs, - the formal parameter list and the
actual parameter list are statically compatible in the sense given below.
Let us recall (5.3.5.) that a formal parameter list of a unit M is dened as
a concatenation of the lists of units belonging to the prex sequence of M.
Static compatibility of parameters.
The list of formal parameters (Pf1, ..., Pfj) is statically compatible with the
list of actual parameters (Pa1, ..., Pak) if j=k and for i=1, ..., k the following
conditions hold:
- if P is an input/output formal parameter then Pai is a WFF of a static
type which is statically compatible with the static type of parameter P, - if P
is an output/inout parameter then Pai is a variable, - if P is a formal function
(procedure) then Pai is a function (procedure) identier, - if P is a formal type
then Pai is a non-primitive type identier.
Semantics .
The allocation of a unit object O is dened if: - the unit and its environment
are determined, - the list of formal parameters is dynamically compatible with
9.1. SEQUENTIAL PRIMITIVE STATEMENTS 69
that of actual parameters (in the sense provided below), - three steps of actions,
called prologue, body, and epilogue, are determined.
Note the dierence between the unit identier and the unit itself. The en-
vironment is the object which becomes the syntactic father of O. In the case
of a formal subprogram, the unit identier may be replaced by one of many
existing units. Denote by O1 the object containing the given unit object alloca-
tion statement. The prologue computes the values for input formal parameters,
determines the addresses of output actual parameters, and determines actual
subprograms/types. The prologue is executed in the environment of the object
O1. The body transfers the control to the statements from the prex sequence
of the given unit. Those statements are executed in the environment of the
object O. The epilogue transmits the values of output formal parameters (in
the environment of the object O1).
Unit's environment
Consider the allocation of a named unit (i.e. it is not a block). A unit
identier has one of the following forms:
(a) M, (b) X.M or X.new M .
Ad (a). Let the static location of the given occurrence of M be determined
by the attribute M of the unit T. Consider three cases:
(a1) M is an attribute of T and it is neither a virtual attribute nor a formal
parameter. Then the declaration of M is determined as (at compilation time)
as the declaration of the attribute M of unit T. The environment of the unit M
is the dynamic container of identier M with respect to the object O1.
(a2) M is a virtual attribute of T. Then the declaration of M is determined
at run-time by the dynamic location of identier M with respect to the given
occurrence (see 6.1.5.). The environment is determined as in (a1).
(a3) M is a formal subprogram of T. Then the declaration of M and its
environment are taken from the dynamic container of the identier M. The
dynamic container is determined with respect to the object O1.
Ad (b). Let X be a well-formed object expression of type R, let M be a
not close attribute of R, and let the expression X be dened. Denote by O2
the non-empty object of unit R0 (R pref* R0) which is pointed to by X. The
cases (a1)-(a3) have to be considered in the same way as the above ones. The
descriptions dier in that the environments are determined with respect to the
object O2. Note that the environment of the object becomes the syntactic father
of the object O.
Dynamic compatibility of parameters.
First let us note the dierence between the determination of dynamic type
for the actual parameter Pa and the formal parameter Pf. The dynamic type
of Pa is determined in the environment of the object O1 (containing the given
allocation). It means that for the formal type S the actual type is taken from
the dynamic container with respect to O1. Recall that it corresponds to the
determination of the valuation of identier S in the SL-chain of O1 (according to
the visibility rules) and taking the text of declaration assigned to S (cf. 6.1.5.).
The dynamic type of Pf is determined in the corresponding environment. It
means that for the formal type S the actual type is taken from the corresponding
dynamic container. In other words, the valuation of identier S is searched for
in the SL-chain of the environment (according to the visibility rules).
The list of formal parameters is dynamically compatible with the list of
actual parameters if the following conditions hold:
70 CHAPTER 9. SEQUENTIAL STATEMENTS.
Array generation.
Syntax.
<array generation>:
Deallocation statement
Syntax.
<object deallocation>:
72 CHAPTER 9. SEQUENTIAL STATEMENTS.
rence of a control statement in the object O of the unit M, in the body of the
unit Mj, where M has the prex sequence M1, ..., Mk=M, and 1<=j<=k.
Syntax .
Semantics.
For j=1, ..., k-1 the execution of the inner statement results in the com-
mencement of the execution of the unit Mj+1. The inner statement in the body
of the unit Mk=M is empty.
The semantics of repeat and exit statements will be dened jointly with the
semantics of a loop statement, see 9.2.3..
Syntax .
Semantics.
In this section we shall describe the semantics of a return statement and
a pseudo-statement end (which bound a unit declaration). An object may be
74 CHAPTER 9. SEQUENTIAL STATEMENTS.
<compound statement):
9.2.1.
<conditional statement>:
| |
|------> else --> <statement list> --------> fi ---------->
<orif list>:
<andif list>:
the boolean expressions B1, .., Bj are evaluated in succession until the rst
one evaluates to true, then the sequence G of statements is executed. If none
of the boolean expressions evaluates to true, then the sequence H is executed.
The conditional statement with the "else" part omitted is equivalent to the
conditional statement with the empty statement following the else symbol. If
the "andif" list occurs instead of the "orif" list, then the expressions B1, ...,
Bj are evaluated in succession until the rst one evaluates to false; then the
sequence H is executed. Otherwise the sequence G is executed. When a boolean
expression occurs instead of an "orif" or "andif" list, then its value controls the
execution of the conditional statement in the standard manner. 9.2.2.
<case statement>:
| |-------------------->|
| | |
| <---- <statement list> <--- : -----| |
| | | |
|-> <arithmetic expression> ---> when ---> ---<integer>-------->| |
| ^ | ^ | |
| | -> <constant> ->| | |
| | | |
| <----- , -------------| |
| |
|-> <character expression> ---> when ---><character constant>->:-| |
^ ^ | ^ | | |
| | |-> <constant> ->| | | |
| | | | |
| |<--------- , --------| | |
| | |
|<------ <statement list> <----------| |
| |
| |
<------------------------------------------------------------|
| |
| |
|-> others ----> <statement list> ---------> esac ---->
case E
when l1:G1
...
when lk:Gk
others H
esac
<iteration statement>:
<loop statement>:
--> while --> <boolean expression> --> do --> <statement list>--> od -->
---> for ---> <simple variable> -->:= --> <arithmetic expression> -->|
|
<------------------------------------------------------------------|
| |
|--> step --> <arithmetic expression>----> to ----->|
| |
|-->downto-->|
|
<---------------------------------------------------|
|
|-> <arithmetic expression> -->do--> <statement list>--->od -->
do
G
od
G1, G3 in G2, etc. Let M be the smallest unit enclosing that occurrence of H. If
k>l then the execution of H causes the termination of the unit body M (jump to
the nal end). Otherwise the iteration statement Gk terminates, and either the
execution of the iteration statement Gk-1 is continued if k<l or the execution
of the outermost iteration statement G1 terminates if k=l. The keyword repeat
may occur just after the sequence of exit's. Then the iteration statement Gk is
continued (if k<=l), i.e., the control is switched not outside but to the beginning
of the loop without the execution of the statements occurring after repeat. If the
statement Gk is a loop statement with the while condition, then the consequtive
iteration starts from the condition evaluation. If it is a for statement, then the
consequtive iteration starts with the change of the controlled variable value.
Remark.
The goto statement is totally deleted from LOGLAN-82 (contrary to other
languages, like ADA where goto within a single unit is allowed). The structured
statements dened above were applied to many examples of known algorithms.
These exercises showed that the proposed structured statements constitute a
good balance point between a non structured goto-label statement and a clas-
sical while statement (which often requires auxiliary control boolean variables).
Notice that the above unit M body is considered to be "non-concatenated", i.e.,
in the case of the jump to end symbol, this end is taken from the body of M,
not from the body of M concatenated with its prex sequence. We stress that
the textual control statements do not lead outside one unit.
End of remark.
A loop statement with condition:
while B
do
G
od
do
if not B then exit fi;
G
od
The controlled variable i must be of discrete type. The statement (*) is equiv-
alent to the following sequence of statements:
80 CHAPTER 9. SEQUENTIAL STATEMENTS.
The statement (**) is equivalent to the above sequence of statements with the
condition Av3>=i replaced by Av3<=i and the assignment i:=i+Av2 replaced
by i:=i-Av2. The variables Av1, Av2, Av3 are ctitious variables introduced
only in order to dene the semantics. The expression step A2 may be omitted
if the value of A2 equals 1. The value of the controlled variable i should not
be modied inside the loop (however, the result of such a modication would
be well-dened). Moreover, its value is determined when loop is terminated
according to the introduced semantics.
Example 9.1. A palindrome is a word which is identical when written from left
to right and conversely. The given algorithm looks for the rst occurrence of a
palindrome in a text and writes its length, (if found).
unit palindrome: procedure;
var i, j, k: integer,
text: arrayof character;
begin
read(j);
array text dim (1:j);
for k:=1 to j
do
read (text(k))
od;
for i:=2 to j
do
k:=1;
while text(k)=text(i-k+1)
do
k:=k+1;
if k>i-k+1
then
write ("found at i-th item");
return
fi
od
od;
write ("not found")
end palindrome;
Example 9.2. A dictionary is a data structure S with the following operations:
member(x, S) - determines whether x is a member of S ,
9.2. COMPOUND STATEMENTS 81
else v.r:=q
fi (* after insert or delete *)
fi (* attach new node q to its father v *)
end help;
begin
member:=new e; insert:=new i; delete:=new d;
inner;
kill(member); kill(insert); kill(delete)
end bst;
var y:t;
...
begin
...
member.x:=y;
attach(member);
if member.elem then ... fi;
...
insert.x:=y;
attach(insert);
...
delete.x:=y;
attach(delete);
...
end;
84 CHAPTER 9. SEQUENTIAL STATEMENTS.
10.
Chapter 10
Exception handling
This section denes the facilities for dealing with errors or other exceptional
situations that may arise during program execution. An exception is an event
that causes a suspention of normal program execution. The occurrence of an
exception is expressed by raising a signal. Executing some actions in response
to the arising of an exceptional situation, is called signal handling.
Signal names are introduced by signal specications. Signals can be raised
by raise statements, or alternatively, their raising is caused by an occurrence of
a run-time error. When an exception arises, the control can be passed to a user-
pointed handler associated with the raised signal. The principles of determining
a handler that responds to the raised signals are presented in 10.3. 10.1
<signal specification>:
---> signal --> <signal name> ---> ( --> <formal par. list> --> ) -->; -->
| | ||
| |-------------------------------->||
|<---------------------- , ---------------------------|
CONTEXT
The signal specication denes signals which can appear in raise statements
and in signal handlers within the scope of the specication. The identiers of
system signals, i.e., signals associated with run-time errors, are not specied in
the signal specication. Signal identiers are not accessible by remote access.
They can occur, however, in a hidden, close or taken list of a unit. 10.2
85
86 CHAPTER 10. EXCEPTION HANDLING
<handlers' declaration>:
---> handlers
|
|-----------> when ---> <signal name> --> : --> <statement list> --|
| | | |
| |<------ , -------| |
| |
|--------<------------------------------------------------------|
|
|-----------> others ----> <statement list> --|
| |
|----------------------------------------> end handlers
|
|-------------->
CONTEXT
Handlers' declaration may appear at the end of the declaration part of a
unit. All identiers visible in the unit and the signal formal parameters may
be used in the handler statements. A handler can handle the named signals. A
handler corresponding to the choice others handles all signals not listed in the
previously specied handlers, including those whose identiers are not visible
within the unit.
Any statement (except inner) whose occurrence in a unit is legal may occur
in the handler.
Restrictions
The formal parameter lists of signals associated with the same handler must
be identical.
Example
----> raise ---> <signal name> --> ( --> <actual par. list> --> ) ----->
| |
|----------------------------------->|
CONTEXT
The signal name in the raise statement ought to be visible in the unit in
which the raise statement appears. The formal and actual parameter lists of
the signal must be compatible.
Example -
10.3. SIGNAL RAISING 87
end handlers
begin
...
call A;
...
raise f;
...
end B;
signal f;
handlers
when f: .....; (* <----------- handler H2 *)
end handlers;
begin
...
raise f;
...
call B;
...
end
block
signal f;
unit A:class;
signal g;
handers
when g: .....; (* <---------- handler G1 *)
end handlers;
begin
...
raise f;
...
raise g;
...
end A;
unit B:A class;
handlers
when f: .....; (* <---------- handler F1 *)
when g: .....; (* <---------- hadller G2 *)
end handlers;
begin
...
raise f;
...
raise g;
...
end B;
begin
10.4. HANDLER EXECUTION 89
...
end;
<handler termination>:
CONTEXT
The statements wind and terminate may appear only within a handler dec-
laration. If none of them occurs in a handler statement list, the statement
terminate is assumed to be the last statement in such a list. The execution of
the statements wind and terminate causes an abnormal termination of the cor-
responding objects from the DL-chain (see below). In that case, the "last-will"
statements are executed before the termination of the objects.
SYNTAX
<last-will statements>:
CONTEXT
Any unit body may be terminated with a sequence of statements labelled
by last_will. They are not executed during normal program execution. The
statement inner must not occur within the "last-will" statements.
SEMANTICS
Let us assume that a signal f raised in an object Ok is handled by a handler
H from an object Oi:
O1 Oi-1 Oi Oi+1 Ok
----- ----- ----- ----- -----
| | <---...<---| |<---| |<----| |<---........<---| |
----- DL ----- DL ----- DL ----- DL -----
| |
| SL |
90 CHAPTER 10. EXCEPTION HANDLING
----- |
| | H-------------------------------->|
-----
The statement return in a handler has a similar eect to that of the statement
return in a procedure. The handler object is deallocated and the control is
passed to the statement just following the corresponding raise.
The execution of the statement wind causes the termination and the deallo-
cation of the objects H, Ok, ..., Oi+1. Before the termination of each of them,
the "last-will" statements, if any, are executed. They complete the object ex-
ecution. In the prexed object the "last-will" statements of each prex are
successively executed, starting from the innermost and ending on the outermost
prex. When the termination and deallocation of these objects is completed,
the control is passed to object Oi, where the computation is continued in a
normal way. Note that the wind statement in the case of k=i is equivalent to
return.
The statement terminate causes the termination and the deallocation of the
objects H, Ok, ..., Oi+1, Oi. They are completed as in the case of wind, i.e.,
the "last-will" statements are executed as well. The control is passed to Oi-1,
if such an object exists. If Oi-1 does not exists, i.e., Oi is the head of the DL-
chain, then this head is terminated (cf. the semantics of the end statement of
coroutine and process).
Remark
If any control statement (raise, detach, attach, etc.) is executed within
the "last-will" statements and the control returns to the interrupted object,
the execution of the "last-will" statements as well as the termination of the
remaining objects in the DL-chain will be continued.
End of remark 10.5.
log_error Any kind of the LOGLAN Running System error (except access
error) like e.g., an attempt to pass the control in a way inconsistent with
the LOGLAN-82 rules, an attempt to kill an active object, etc.
10.5. SYSTEM SIGNALS 91
con_error The value of an index expression exceeds the range of array indices
or the array bounds are incorrect.
sys_error Any kind of system error like e.g., input-output error, parity error,
etc.
Some other errors may also be introduced as system errors but are not predened
in the language.
92 CHAPTER 10. EXCEPTION HANDLING
11.
Chapter 11
Processes
Attention. This chapter need to be rewritten since the notion of process as
implemented in the distributed version of Loglan82 diers from the rst version;
see User's guide and micro-manual.
Let us consider a snap-shot of a program's computation. This snap-shot
is called a conguration. Up till now a conguration has consisted of a nite
number of objects creating a number of coroutine chains. The main program is
the only chain with the head of process type. Moreover, exactly one object has
been considered "active" - i.e., its statements have been executed by a phys-
ical processor. By a physical processor we mean here an actual processor as
well as the portion of time of a central unit. A conguration with many ac-
tive objects illustrates the computation of a program with parallel statements.
Concurrent computation to some extent generalizes coroutines, i.e., a cong-
uration may contain many coroutine chains with heads of coroutine type and
many process chains with heads of process type. The fundamental notion is
that of a process. A process may be treated as a sequential program - only one
statement of a process is being executed at a time. A parallel program consists
of a number of processes. In LOGLAN-82 a process is a system type. A process
object may be generated by means of the new statement. The generated process
object is suspended with the execution of the return statement. This process
may be resumed by means of the resume statement. After resumption, process
statements are executed by a new processor, concurrently with the other active
processes. During its computations, the process may suspend its actions (but
not the actions of other processes) by means of the stop statement, then it may
be resumed again, and so on. Observe that the attach and detach statements
switch the processor from one object to another, while the resume and stop
statements acquire and release a processor respectively. Resumption of a corou-
tine chain is connected with the control transfer from the active coroutine chain.
Resumption of a process chain acquires new processor for that chain. Similarly,
suspension of a coroutine chain gives the control back to another chain, while
suspension of a process chain releases the processor. Note that a process object
is more complex than a coroutine object. So coroutine operations are more
ecient with respect to time and space.
In order to deal with communication among processes (e.g., by messages)
as well as their competition in acquiring a resource (such as a shared variable)
one should have the ability to dene some synchronizing operations. Those
93
94 CHAPTER 11. PROCESSES
13.
96 CHAPTER 11. PROCESSES
Chapter 12
File processing
13.1.
97
98 CHAPTER 12. FILE PROCESSING
internal le must be associated with that external one. When the generation of
an internal le is in eect, the le is said to be open.
SYNTAX
<file declaration>:
<file generation>:
--> open
|
|
(
|
<object expression> ---> , ---> <string> ----> ) ------->
| |
|-------------------->|
SEMANTICS
Variables of le type are declared as any other variables of class type. An
object of le type (internal le) has no attributes visible to the programmer. File
generation diers from class generation. It is performed by an open statement.
If the second argument appears, then a new internal le associated with an
external one (identied by the string) is generated. The reference to such an
internal le is set to the variable of type le occurring as the rst argument. If
there is only one argument, then a new local le is generated and the reference
to the corresponding internal le is set to the variable of type le occurring as
the argument of the operation. For instance:
open(X, "teletype")
generates a new internal le associated with the external le "teletype".
Similarly
open(Y)
generates a new local le referenced by Y.
Thus the operation new is not applicable to les. Moreover, remote access
to internal les is not permissible (no attributes visible to the user). Except le
generation, remote access and prexing, le type can be applied as any other
class type. In particular, expressions of le type may be compared, assignments
on variables of type le are allowed, the user can declare a function of type le,
etc.
Remark
External le processing is not predened in the language. The operations
on external les, such as le creation, le deletion, le protection and so on,
depend on the given le system. They may be introduced into the language as
standard functions or procedures in the individual implementation.
End of remark
After processing has been completed on a le, it can be closed and the
corresponding internal le may be deallocated. These actions are performed by
the kill statement, where the argument points to the corresponding internal le.
13.3.
12.3. BINARY INPUT-OUTPUT 99
---> put ---> (---> <object expression>-> , ---> <expression list> --> ) ---->
---> get ---> (---> <object expression>-> , ---> <expression list> --> ) ---->
SEMANTICS
Operation put transmits a sequence of bytes from memory to an open le
(dened by the rst parameter) at the current le position. This sequence of
bytes is dened by the list of expressions. For any list element, going from left
to right, the value of the expression is computed. If this value is primitive,
then the transmitted bytes correspond exactly to the internal representation
of the value. If the value is a reference to an object, then the transmitted
bytes cover all non-system attributes of the referenced object. If this value is
none, then no transmission is performed. Operation get transmits a sequence
of bytes from an open le (dened by the rst parameter) to the memory. If a
list element is an object expression, then the transmitted bytes cover all non-
system attributes of the referenced object (hence, if the value of this expression
is none, then no transmission is performed). Otherwise, list element must be
a variable of primitive type, and then the transmitted bytes cover exactly its
internal representation. The sequence of transmitted bytes starts at the current
le position.
For instance, let x be a real, i an integer and Y a reference variable to an
object of type A:
unit A:class(j:integer);
var u, v, w:real;
end A;
<size operator>:
<eof operator>:
<position operator>:
<seek operation>:
--> seek --> ( --> <object expression> --> , --> <arithmetic expression> --> ) -->
SEMANTICS
The size operator of integer type gives the number of bytes of the internal
representation of an argument. If the argument is an expression of primitive
type, then the returned value may be computed at compilation time and equals
the number of bytes of the internal representation of that primitive type. If
the argument is an expression of class or array type, then the returned value
gives the number of bytes of the object referenced by the argument (except
system-attributes). If the object none is referenced, then the returned value
is 0. Another kind of argument of size operator is type. It may be either an
explicitly written type or a formal type. If the argument is a primitive type or
a class type, then its length in bytes computed at compilation time is returned.
If the argument is an array type, then its size cannot be established and so the
expression is incorrect. If the argument is a formal type, the returned value
is dened similarly but computed at run time. Thus when the actual type is
array the run time error is raised. In all these cases size operator informs the
user about the length in bytes of the internal representation of the argument
(if possible). In particular, the argument may be a le and then the length in
bytes of the corresponding external or local le is returned.
The argument of the boolean operator eof must be a le. It returns the value
true i the current position of the le exceeds or equals its size. The argument of
the integer operator position must also be a le. It returns the current position
of the le. The rst argument of the seek operation must be a le. Then the
current position of this le is set to the value dened by the second argument
of the operation. 13.5.
|--------------------------->|
| |
--> read --> ( --> <object expression> ---> , --> <variable list> --> ) ---->
|------------------------------------>|
| |
->writeln --> ( --> <object expression> --> ) ------------------------->
|
|
->write --> ( -------------->|
| |
<object expression>-> , -> <expression> ----> <format> ---> ) -------->
^ |
|<--------- , ------------|
<format>:
------------------------------------------------------------------->
| ^ ^
|-> : -> <arithmetic expression>-|- : -> <arithmetic expression> -|
SEMANTICS.
An input statement read(F, y1, ..., yk) is correct if F is a le and y1, ..., yk
are variables of integer, real, or character type. File F is treated as a sequence
of symbols. The execution of that statement causes the input data represented
as the corresponding sequence of symbols from le F to be read, decoded and
assigned to y1, ..., yk respectively. The input statement is dened if the as-
signments are dened (going from left to right). An output statement write(F,
E:A1) is correct if F is a le, E is an expression of a primitive type, and A1 is an
arithmetic expression of integer type. Consider rst the case where expression E
is of integer type. The value of expression A1 determines the number of symbols
to be outputed on le F. If the specied number of symbols is greater (less) than
the number of symbols required for the representation of the value of expression
E, then the value of E is preceded by the appropriate number of blanks (then
the format indicates a standard one (dependent on an individual implementa-
tion). If expression E is of real type, then the output statement may be of the
form write(F, E:A1:A2), here A1 and A2 are arithmetic expressions of integer
type. The meaning of the expression A1 is hat described above, the value of the
expression A2 determines the number of digits following the decimal point. In
case of an output statement of the form write(F, E:A1), where E is of real type,
the exponent part is always present. The absence of format indicates a standard
one (dependent on an individual implementation). An output statement of the
form write(F, E) where E is an expression of character type causes the external
representation of E to be outputed on le F. If E is an expression of string type,
then its external representation is outputed on le F. In this ase format A1 may
appear and denes the maximal number of symbols which may be outputed,
102 CHAPTER 12. FILE PROCESSING
i.e., if the length of a string exceeds the dened format, then the last symbols
are dropped. In the statement write(F, E:A1:A2) format A2 is computed rst
(if present), format A1 is computed next (if resent), and nally the value of
E is computed and outputed according to the dened formats. The execution
of an output statement with a list results in the successive evaluations of the
expressions A2, A1, E, and in the output of the computed value. Statement
writeln outputs the end of line symbol after output is completed. If writeln has
only the le parameter, then the end of the line symbol is outputed on le F.
If no le is specied, a default standard input or standard output le is used.
At the beginning of program execution, these les are open and associated with
two implementation dened external les. 13.6.
[4] G. Mirkowska and A. Salwicki. Problems and theories inspired by the loglan
project. In Algorithmic Logic, pages 298347. PWN & D.Reidel, 1987.
105