-
Notifications
You must be signed in to change notification settings - Fork 1
/
report.tex
1524 lines (1093 loc) · 59.5 KB
/
report.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
\documentclass[12pt]{article}
\usepackage{report}
\title{AX Oberon-2/07 Language Report}
\begin{document}
\maketitle
\abstract{
This report describes the syntax and semantics of the programming language Oberon-2/07 as it is supported by the AX Oberon compiler.
}
\tableofcontents
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Introduction}
This report is in the tradition of other Oberon language reports, defining the language supported by the compiler. This document used {\em The Programming Language Oberon-2} by H. Hössenböck and N. Wirth as it's base. Also the Oberon-07 document {\em The Programming Language Oberon (Revision 1.10.2013/3.5.2016)}, by N. Wirth.
Oberon-07 seems to be a refinement of Oberon-2 with some features taken out. We will support a common maximum variant of the language.
Also we extend the definition of Oberon to include the following updates:
\begin{itemize}
\item Source files can be UTF-8 files. Identifiers, characters and strings can be composed of valid UTF-8 characters.
\item \STRING\ type which is equivalent to \ARRAY\ \OF\ \CHAR.
\end{itemize}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Syntax}
To describe the syntax, an extended Backus-Naur Formalism called EBNF is used. Brackets [ and ] denote optionality of the enclosed sentential form, and braces \{ and \} denote its repetition (possibly 0 times). Syntactic entities (non-terminal symbols) are denoted by English words expressing their intuitive meaning. Symbols of the language vocabulary (terminal symbols) are denoted by strings enclosed in quote marks or words written in capital letters, so-called reserved words.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Vocabulary and representation}
The representation of symbols in terms of characters is defined using UTF-8. Symbols are identifiers, numbers, operators, delimiters, and comments. The following lexical rules must be observed. Blanks and line breaks must not occur within symbols (except in comments). They are ignored unless they are essential to separate two consecutive symbols. Capital and lower-case letters are considered as being distinct.
There is some support for emoji as identifiers, emoji are treated as a non-digit alphabetic characters.
\begin{enumerate}
\item Identifiers are sequences of letters and digits. The first character must be a letter.
\begin{lstlisting}[style=ebnf]
Identifier = Letter {Letter | Digit | '_' }.
\end{lstlisting}
Examples: \lstinline!x scan Oberon G3 first_Letter olá Liberté χαῖρε!
\item Numbers are (unsigned) integers. Integers are sequences of digits.
If the constant is specified with the suffix \lstinline!H!, the representation is hexadecimal otherwise it is decimal.
\begin{lstlisting}[style=ebnf]
integer = digit {digit} | digit {hexDigit} "H".
hexDigit = digit|"A"|"B"|"C"|"D"|"E"|"F"|"a"|"b"|"c"|"d"|"e"|"f".
digit = "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9".
\end{lstlisting}
A real number always contains a decimal point. Optionally it may also contain a decimal scale factor.
The letter \lstinline!E! (or \lstinline!D!) means "times ten to the power of". A real number is of type \REAL.
\begin{lstlisting}[style=ebnf]
real = digit {digit} "." {digit} [ScaleFactor].
ScaleFactor = ("E" | "D") ["+" | "-"] digit {digit}.
\end{lstlisting}
\begin{lstlisting}[style=example]
2020 0DH 12.3 4.567E8 0.55712566D-6
\end{lstlisting}
\item \BOOLEAN\ constants are \TRUE\ and \FALSE. \label{bool-consts}
\item Character constants are denoted by the ordinal number of the character in hexadecimal notation followed by the letter X or by the ASCII symbol of the character embraced by single quotes.
\begin{lstlisting}[style=ebnf]
character = digit {hexDigit} "X" | "’" char "’".
\end{lstlisting}
\begin{lstlisting}[style=example]
CONST a = 'A';
b = 13X;
\end{lstlisting}
\item Strings are sequences of characters enclosed in single (\lstinline!'!) or double (\lstinline!"!) quote marks. The opening quote must be the same as the closing quote and must not occur within the string. The number of characters in a string is called its length. A string of length 1 can be used wherever a character constant is allowed and vice versa.
\begin{lstlisting}[style=ebnf]
string = ' " ' {char} ' " ' | " ' " {char} " ' ".
\end{lstlisting}
\begin{lstlisting}[style=example]
"Oberon-2" "Don't worry!" "x"
\end{lstlisting}
\item Operators and delimiters are the special characters, character pairs, or reserved words listed below. These reserved words cannot be used in the role of identifiers. Reversed words can be uppercase or lowercase, not combinations of both.
\begin{lstlisting}[style=example]
+ := - * = / # ~ < & > . <= , >= ( ) : [ ] ; | .. ^ { }
ARRAY BEGIN BY CASE CONST DIV DO ELSE ELSIF END EXIT FOR IF IMPORT IN LOOP
MOD MODULE NIL OF OR POINTER PROCEDURE RECORD REPEAT RETURN THEN TO TYPE
UNTIL VAR WHILE
\end{lstlisting}
\item Comments may be inserted between any two symbols in a program. They are arbitrary character sequences between (* *).
Comments do not affect the meaning of a program.
\end{enumerate}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Declarations and scope rules}
\label{declarations}
Every identifier occurring in a program must be introduced by a declaration, unless it is a predefined identifier. Declarations also serve to specify certain permanent properties of an object, such as whether it is a constant, a type, a variable, or a procedure.
The scope of an object x extends textually from the point of its declaration to the end of the block (module, procedure, or record) to which the declaration belongs and hence to which the object is local. It excludes the scopes of equally named objects which are declared in nested blocks. The scope rules are:
The scope rule has the following amendments:
\begin{enumerate}
\item No identifier may denote more than one object within a given scope (i.e. no identifier may be declared twice in a block);
\item An object may only be referenced within its scope;
\item A type T of the form \POINTER\ \TO\ T1 (see \ref{pointers}) can be declared at a point where T1 is unknown. The declaration of T1 must follow in the same block to which T is local;
\item Field identifiers of a record declaration (see \ref{records}) are valid in field designators only.
\end{enumerate}
An identifier declared in a module block may be followed by an export mark (\lstinline!*! or \lstinline!-!) in its declaration to indicate that it is exported. An identifier \lstinline!x! exported by a module \lstinline!M! may be used in other modules, if they import M (see \ref{modules}). The identifier is then denoted as \lstinline!M.x! in these modules and is called a qualified identifier. Variables and record fields marked with \lstinline!-! in their declaration are read-only in importing modules.
\begin{lstlisting}[style=ebnf]
Qualident = [ident "."] ident.
IdentDef = ident ["*" | "-"].
\end{lstlisting}
The following identifiers are predefined; their meaning is defined in the indicated sections:
\begin{tabbing}
XXXXXXXXXX \= \kill
\ABS \> (\ref{predefined}) \\
\ASH \> (\ref{predefined}) \\
\ASSERT \> (\ref{predefined}) \\
\BOOLEAN \> (\ref{types-basic}) \\
\CAP \> (\ref{predefined}) \\
\CHAR \> (\ref{types-basic}) \\
\CHR \> (\ref{predefined}) \\
\COPY \> (\ref{predefined}) \\
\DEC \> (\ref{predefined}) \\
\EXCL \> (\ref{predefined}) \\
\FALSE \> (\ref{bool-consts}) \\
\FLOOR \> (\ref{predefined}) \\
\FLT \> (\ref{predefined}) \\
\HALT \> (\ref{predefined}) \\
\INC \> (\ref{predefined}) \\
\INCL \> (\ref{predefined}) \\
\INTEGER \> (\ref{types-basic}) \\
\LEN \> (\ref{predefined}) \\
\LONG \> (\ref{predefined}) \\
\MAX \> (\ref{predefined}) \\
\MIN \> (\ref{predefined}) \\
\NEW \> (\ref{predefined}) \\
\ODD \> (\ref{predefined}) \\
\ORD \> (\ref{predefined}) \\
\REAL \> (\ref{types-basic}) \\
\SET \> (\ref{types-basic}) \\
\SIZE \> (\ref{predefined}) \\
\SHORT \> (\ref{predefined}) \\
\STRING \> (\ref{types-basic}) \\
\TRUE \> (\ref{bool-consts}) \\
\WriteInt \> (\ref{predefined}) \\
\WriteBoolean \> (\ref{predefined}) \\
\WriteLn \> (\ref{predefined}) \\
\end{tabbing}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Constant declarations}
A constant declaration associates an identifier with a constant value.
\begin{lstlisting}[style=ebnf]
ConstantDeclaration = IdentDef "=" ConstExpression.
ConstExpression = expression.
\end{lstlisting}
A constant expression is an expression based on constant values and constant variables. Examples of constant declarations are:
\begin{lstlisting}[style=example]
N = 100
limit = 2 * N - 1
fullSet = {MIN(SET) .. MAX(SET)}
\end{lstlisting}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Type declarations}
\label{types}
A data type determines the set of values which variables of that type may assume, and the operators that are applicable. A type declaration is used to associate an identifier with the type. Such association may be with unstructured (basic) types, or it may be with structured types, in which case it defines the structure of variables of this type and, by implication, the operators that are applicable to the components. There are two different structures, namely arrays and records, with different component selectors.
\begin{lstlisting}[style=ebnf]
TypeDeclaration = IdentDef "=" type.
type = Qualident | ArrayType | RecordType | PointerType.
\end{lstlisting}
Examples:
\begin{lstlisting}[style=example]
Table = ARRAY 10 OF INTEGER
Tree = POINTER TO Node
Node = RECORD key: INTEGER;
left, right: Tree
END
\end{lstlisting}
\subsection{Basic types}
\label{types-basic}
The following basic types are denoted by predeclared identifiers. The associated operators are defined in \ref{operators}, and the predeclared function procedures in \ref{predefined}. The values of a given basic type are the following:
\begin{enumerate}
\item \BOOLEAN\ -- the truth values \TRUE\ and \FALSE.
\item \INTEGER\ -- the integers of a 64-bit signed integer, between \MIN(\INTEGER)\ and \MAX(\INTEGER).
\item \REAL\ -- double precision floating point type. Usually IEEE-754 64 bit floating point, numbers between \MIN(\REAL) and \MAX(\REAL).
\item \CHAR\ -- character type, sufficient large enough to represent any supported character code point (32 bits on systems that support Unicode), between \MIN(\CHAR)\ and \MAX(\CHAR).
\item \STRING\ -- character array type. \ARRAY\ \OF\ \CHAR\ is equivalent to \STRING.
\item \SET\ -- the sets of integers between 0 and \MAX(\SET).
\end{enumerate}
Types \INTEGER\ and \REAL\ together they are called numeric types. They form a hierarchy; the larger type includes (the values of) the smaller type:
\begin{quote}
\REAL\ $\supseteq$ \INTEGER\
\end{quote}
Types \lstinline!SMALLINT!, \lstinline!LONGINT!, and \lstinline!HUGEINT!, are predefined and aliased to \INTEGER. Likewise \lstinline!LONGREAL!, is alliased to \REAL.
\subsection{Array types}
\begin{lstlisting}[style=ebnf]
ArrayType = ARRAY [Length {"," Length}] OF Type.
Length = ConstExpression.
\end{lstlisting}
A type of the form
\begin{lstlisting}[style=example]
ARRAY L0, L1, ..., Ln OF T
\end{lstlisting}
is understood as an abbreviation of
\begin{lstlisting}[style=example]
ARRAY L0 OF ARRAY L1 OF ... ARRAY Ln OF T
\end{lstlisting}
Arrays declared without length are called open arrays.
Examples of array types:
\begin{lstlisting}[style=example]
ARRAY 10, N OF INTEGER
ARRAY OF CHAR
\end{lstlisting}
Arrays can't be assigned to each other, the elements have to be copied individually.
\subsection{Record types}
\label{records}
A record type is a structure consisting of a fixed number of elements of possibly different types. The record type declaration specifies for each element, called field, its type and an identifier which denotes the field. The scope of these field identifiers is the record definition itself, but they are also visible within field designators (see \ref{operands}) referring to elements of record variables.
\begin{lstlisting}[style=ebnf]
RecordType = RECORD ["("BaseType")"] FieldListSequence END.
BaseType = Qualident
FieldListSequence = FieldList {";" FieldList}.
FieldList = [IdentList ":" type].
IdentList = IdentDef {"," IdentDef}.
\end{lstlisting}
Examples of record types:
\begin{lstlisting}[style=example]
RECORD
day, month, year: INTEGER
END
RECORD
name, firstname: ARRAY 32 OF CHAR;
age: INTEGER;
salary: REAL
END
\end{lstlisting}
Record types are extensible, i.e. a record type can be declared as an extension of another record type. In the example:
\begin{lstlisting}[style=example]
T0 = RECORD x: INTEGER END
T1 = RECORD (T0) y: REAL END
\end{lstlisting}
T1 is a (direct) extension of T0 and T0 is the (direct) base type of T1 (see Appendix \ref{type-rule}).
An extended type T1 consists of the fields of its base type and of the fields which are declared in T1. Identifiers declared in the extension must be different from the identifiers declared in its base type(s).
Records can't be assigned to each other, the elements have to be copied individually.
\subsection{Pointer types}
\label{pointers}
Variables of a pointer type P assume as values pointers to variables of some type T. T is called the pointer base type of P and must be a record or array type.
\begin{lstlisting}[style=ebnf]
PointerType = POINTER TO Type.
\end{lstlisting}
\begin{itemize}
\item If p is a variable of type P = \POINTER\ \TO\ T, a call of the predeclared procedure \NEW(p) (see \ref{predefined}) allocates a variable of type T in free storage.
\item If T is a record type or an array type with fixed length, the allocation has to be done with NEW(p).
\item If T is an n-dimensional open array the allocation has to be done with \NEW(p, $e_0$, ... $e_{n-1}$), where T is allocated with lengths given by the expressions $e_0$, ... $e_{n-1}$.
\end{itemize}
In either case a pointer to the allocated variable is assigned to p, p is of type P. The referenced variable p\lstinline!^! (pronounced as p-referenced) is of type T.
Any pointer variable may assume the value \NIL, which points to no variable at all. All pointer variables are initialized to \NIL.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Variable declarations}
Variable declarations serve to introduce variables and associate them with identifiers that must be unique within the given scope. They also serve to associate fixed data types with the variables.
\begin{lstlisting}[style=ebnf]
VariableDeclaration = IdentList ":" type.
\end{lstlisting}
Variables whose identifiers appear in the same list are all of the same type. Examples of variable declarations (refer to examples in section \ref{types}):
\begin{lstlisting}[style=example]
i, j, k: INTEGER
x, y: REAL
p, q: BOOLEAN
s: SET
a: ARRAY 100 OF INTEGER
w: ARRAY 16 OF
RECORD count: INTEGER
END
t: Tree
\end{lstlisting}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Expressions}
Expressions are constructs denoting rules of computation whereby constants and current values of variables are combined to derive other values by the application of operators and function procedures. Expressions consist of operands and operators. Parentheses may be used to express specific associations of operators and operands.
\subsection{Operands}
\label{operands}
With the exception of sets and literal constants, i.e. numbers, operands are denoted by designators. A designator consists of an identifier referring to the constant, variable, or procedure to be designated. A designator consists of an identifier referring to a constant, variable, or procedure.
This identifier may possibly be followed by selectors, if the designated object is an element of a structure.
\begin{lstlisting}[style=ebnf]
designator = Qualident {"." ident | "[" ExprList "]" | "^" }.
ExprList = Expr {"," Expr}.
\end{lstlisting}
If A designates an array, then A[E] denotes that element of A whose index is the current value of the expression E. The type of E must be an integer type. A designator of the form a[$e_0$, $e_1$, ..., $e_n$] stands for a[$e_0$][$e_1$]...[$e_n$]. A \STRING\ variable functions as an \ARRAY\ of \CHAR, thus accepts array selectors.
If r designates a record, then r.f denotes the field f of r.
If p designates a pointer, p\^{} denotes the variable which is referenced by p. The designators p\^{}.f and p\^{}[e] may be abbreviated as p.f and p[e], i.e. record and array selectors imply dereferencing. If a or r are read-only, then also a[e] and r.f are read-only.
If the designated object is a variable, then the designator refers to the variable's current value.
Examples of designators (see examples in section \ref{types}):
\vspace{2mm}
\begin{tabular}{l|l}
designator & type \\
\hline
i & (\INTEGER) \\
a[i] & (\INTEGER) \\
w[3].name[0] & (\CHAR) \\
w[3].count & (\INTEGER) \\
\end{tabular}
\subsection{Operators}
\label{operators}
The syntax of expressions distinguishes between four classes of operators with different precedences (binding strengths). The operator ~ has the highest precedence, followed by multiplication operators, addition operators, and relations. Operators of the same precedence associate from left to right. For example, x-y-z stands for (x-y)-z.
\begin{lstlisting}[style=ebnf]
expression = SimpleExpression [relation SimpleExpression].
relation = "=" | "#" | "<" | "<=" | ">" | ">=" | IN.
SimpleExpression = [ "+" | "-" ] term {AddOperator term}.
AddOperator = = "+" | "-" | OR
term = factor {MulOperator factor}.
MulOperator = "*" | "/" | DIV | MOD | "&".
factor = number | character | string | NIL | set
| designator [ experssion ]
| "(" expression ")"
| "~" factor.
set = "{" [element {"," element}] "}".
element = expression [ ".." expression]
\end{lstlisting}
The available operators are listed in the following tables. In some instances, several different operations are designated by the same operator symbol. In these cases, the actual operation is identified by the type of the operands.
\subsubsection{Logical operators}
\begin{tabular}{l|l}
symbol & result \\
\hline
\OR & logical disjunction \\
\& & logical conjuction \\
\~{} & negation
\end{tabular}
\vspace{2mm}
The operators \& and \OR\ evaluate their operands only until an conclusive result is obtained (first \TRUE\ value for \OR, first \FALSE\ value for \&).
\subsubsection{Arithmetic operators}
\begin{tabular}{l|l}
symbol & result \\
\hline
+ & sum \\
- & difference \\
\** & product \\
/ & quotient \\
\DIV & integer quotient \\
\MOD & modulus \\
\end{tabular}
\vspace{2mm}
The operators +, -, *, and / apply to operands of numeric types. The type of the result is that
operand's type which includes the other operand's type, except for division (/), where the result is the real type which includes both operand types. When used as operators with a single operand, - denotes sign inversion and + denotes the identity operation.
The operators \DIV\ and \MOD\ apply to integer operands only. They are related by the following formulas defined for any dividend x and positive divisors y:
\begin{lstlisting}[style=example]
x = (x DIV y) * y + (x MOD y)
0 ≤ (x MOD y) < y
\end{lstlisting}
\subsubsection{Set Operators}
\begin{tabular}{l|l}
symbol & result \\
\hline
+ & union \\
- & difference (x - y = x * (-y)) \\
\** & intersection \\
/ & symmetric set difference (x / y = (x-y) + (y-x))\\
\end{tabular}
\vspace{2mm}
Set operators apply to operands of type \SET\ and yield a result of type \SET.
The monadic minus sign denotes the complement of x, i.e. -x denotes the set of integers between 0 and \MAX(\SET) which are not elements of x. Set operators are not associative ((a+b)-c \# a+(b-c)).
A set constructor defines the value of a set by listing its elements between curly brackets. The elements must be integers in the range 0..\MAX(\SET). A range a..b denotes all integers in the interval [a, b].
\subsubsection{Relations}
\begin{tabular}{l|l}
symbol & result \\
\hline
= & equal \\
\# & unequal \\
< & less \\
<= & less or equal \\
>= & greater \\
> & greater or equal \\
\IN & set membership \\
\end{tabular}
\vspace{2mm}
Relations yield \BOOLEAN\ results. The ordering relations <, <=, >, and >= apply to the numeric types, CHAR, strings and character arrays containing 0X as a terminator. The relations = and \# also apply to the type \BOOLEAN\ and \SET, as well as to pointer types (including the value \NIL). x \IN\ s stands for "x is an element of s". x must be of an integer type, and s of type \SET.
Examples of expressions:
\begin{tabbing}
XXXXXXXXXXX \= \kill
1987 \> (\INTEGER) \\
i \DIV\ 3 \> (\INTEGER) \\
~p \OR\ q \> (\BOOLEAN) \\
a[i+j] * a[i-j] \> (\INTEGER) \\
(0<=i) \& (i<100) \> (\BOOLEAN) \\
k \IN\ {i..j-1} \> (\BOOLEAN) \\
t.key = 0 \> (\BOOLEAN) \\
\end{tabbing}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Statements}
Statements denote actions. There are elementary and structured statements. Elementary statements are not composed of any parts that are themselves statements. They are the assignment, the procedure call, and the return.
Structured statements are composed of parts that are themselves statements. They are used to express sequencing and conditional, selective, and repetitive execution.
\begin{lstlisting}[style=ebnf]
statement = [assignment | ProcedureCall | IfStatement | WhileStatement
| RETURN [expression] ].
\end{lstlisting}
\subsection{Assignments}
\label{assignment}
The assignment serves to replace the current value of a variable by a new value specified by an expression. The assignment operator is written as ":=" and pronounced as becomes.
\begin{lstlisting}[style=ebnf]
assignment = designator ":=" expression.
\end{lstlisting}
The type of the expression must be included by the type of the variable
Examples of assignments (see examples in \ref{types}):
\begin{lstlisting}[style=example]
i := 0
p := i = j
x := i + 1
a[i] := (x+y) * (x-y)
t.key := i
w[i+1].count := 100
\end{lstlisting}
\subsection{Procedure calls}
A procedure call serves to activate a procedure. The procedure call may contain a list of actual parameters which are substituted in place of their corresponding formal parameters defined in the procedure declaration (see section \ref{procedures}). The correspondence is established by the positions of the parameters in the lists of actual and formal parameters respectively. There exist two kinds of parameters: variable and value parameters.
In the case of variable parameters, the actual parameter must be a designator denoting a variable. If it designates an element of a structured variable, the selector is evaluated when the formal/actual parameter substitution takes place, i.e. before the execution of the procedure. If the parameter is a value parameter, the corresponding actual parameter must be an expression. This expression is evaluated prior to the procedure activation, and the resulting value is assigned to the formal parameter which now constitutes a local variable (see also \ref{parameters}).
\begin{lstlisting}[style=ebnf]
ProcedureCall = designator [ActualParameters].
\end{lstlisting}
Examples of procedure calls:
\begin{lstlisting}[style=example]
WriteInt(j * 2 + 1)
\end{lstlisting}
\subsection{Statement sequences}
Statement sequences denote the sequence of actions specified by the component statements which are separated by semicolons.
\begin{lstlisting}[style=ebnf]
StatementSequence = statement {";" statement}.
\end{lstlisting}
\subsection{\IF\ statements}
\begin{lstlisting}[style=ebnf]
IfStatement = IF expression THEN StatementSequence
{ELSIF expression THEN StatementSequence}
[ELSE StatementSequence]
END.
\end{lstlisting}
\IF\ statements specify the conditional execution of guarded statements. The boolean expression preceding a statement is called its guard. The guards are evaluated in sequence of occurrence, until one evaluates to \TRUE, whereafter its associated statement sequence is executed. If no guard is satisfied, the statement sequence following the symbol \ELSE\ is executed, if there is one.
\begin{lstlisting}[style=example]
IF (ch >= "A") & (ch <= "Z") THEN ReadIdentifier
ELSIF (ch >= "0") & (ch <= "9") THEN ReadNumber
ELSIF ch = 22X THEN ReadString
END
\end{lstlisting}
\subsection{\CASE\ statement}
\CASE\ statements specify the selection and execution of a statement sequence according to the value of an expression.
First the case expression is evaluated, then that statement sequence is executed whose case label list contains the obtained value.
The case expression must either be of an integer type that includes the types of all case labels, or both the case expression and the case labels must be of type \CHAR. Case labels are constants, and no value must occur more than once. If the value of the expression does not occur as a label of any case, the statement sequence following the symbol \ELSE\ is selected, if there is one, otherwise the program is aborted.
\begin{lstlisting}[style=ebnf]
CaseStatement = CASE Expression OF
Case
{"|" Case}
[ELSE StatementSequence]
END.
Case = [CaseLabelList ":" StatementSequence].
CaseLabelList = CaseLabels {"," CaseLabels}.
CaseLabels = ConstExpression [".." ConstExpression].
\end{lstlisting}
\begin{lstlisting}[style=example]
CASE ch OF
"A" .. "Z": ReadIdentifier
| "0" .. "9": ReadNumber
| "'",'"':ReadString
ELSE SpecialCharacter
END
\end{lstlisting}
\subsection{\WHILE\ statements}
\WHILE\ statements specify repetition. If the Boolean expression (guard) yields \TRUE, the statement sequence is executed. The expression evaluation and the statement execution are repeated as long as the Boolean expression yields \TRUE.
\begin{lstlisting}[style=ebnf]
WhileStatement = WHILE expression DO StatementSequence END.
\end{lstlisting}
Examples:
\begin{lstlisting}[style=example]
WHILE j > 0 DO
j := j DIV 2; i := i+1
END
\end{lstlisting}
\subsection{\REPEAT\ statments}
A \REPEAT\ statement specifies the repeated execution of a statement sequence until a condition specified by a Boolean expression is satisfied. The statement sequence is executed at least once.
\begin{lstlisting}[style=ebnf]
RepeatStatement = REPEAT StatementSequence UNTIL Expression.
\end{lstlisting}
\subsection{\FOR\ statements}
A \FOR\ statement specifies the repeated execution of a statement sequence for a fixed number of times while a progression of values is assigned to an numeric integer or \CHAR\ variable called the control variable of the for statement. The variable should be pre-defined earlier in the program.
\begin{lstlisting}[style=ebnf]
ForStatement = FOR ident ":=" Expression TO Expression
[BY ConstExpression] DO StatementSequence END.
\end{lstlisting}
The statement
\begin{lstlisting}[style=example]
FOR v := low TO high BY step DO statements END
\end{lstlisting}
is equivalent to
\begin{lstlisting}[style=example]
v := low; temp := high;
IF step > 0 THEN
WHILE v <= temp DO statements; v := v + step END
ELSE
WHILE v >= temp DO statements; v := v + step END
END
\end{lstlisting}
\lstinline!low! must be assignment compatible with \lstinline!v!, \lstinline!high! must be expression compatible (i.e. comparable) with \lstinline!v!, and step must be a nonzero constant expression of an integer type. If step is not specified, it is assumed to be 1.
Examples:
\begin{lstlisting}[style=example]
FOR i := 0 TO 79 DO k := k + a[i] END
FOR i := 79 TO 1 BY -1 DO a[i] := a[i-1] END
\end{lstlisting}
\subsection{\LOOP\ statements}
A \LOOP\ statement specifies the repeated execution of a statement sequence. It is terminated upon execution of an exit statement within that sequence (see \ref{return}).
\begin{lstlisting}[style=example]
LoopStatement = LOOP StatementSequence END.
\end{lstlisting}
Example:
\begin{lstlisting}[style=example]
LOOP
ReadInt(i);
IF i < 0 THEN EXIT END;
WriteInt(i)
END
\end{lstlisting}
Loop statements are useful to express repetitions with several exit points or cases where the exit condition is in the middle of the repeated statement sequence.
\subsection{\BEGIN\ statements}
This is non-standard Oberon. A begin statement specifies a collection of statements. There is no looping function. It is terminated upon execution of an exit statement within that sequence (see \ref{return}), or completion of the final statement in the \BEGIN\ \END\ block.
\begin{lstlisting}[style=example]
LoopStatement = BEGIN StatementSequence END.
\end{lstlisting}
Example:
\begin{lstlisting}[style=example]
BEGIN
ReadInt(i);
IF i < 0 THEN EXIT END;
WriteInt(i)
END
\end{lstlisting}
\subsection{\RETURN\ and \EXIT\ statements}
\label{return}
A return statement consists of the symbol \RETURN, possibly followed by an expression. It indicates the termination of a procedure, and the expression specifies the result of a function procedure. Its type must be identical to the result type specified in the procedure heading (see \ref{procedures}).
Function procedures require the presence of a return statement indicating the result value. There may be several, although only one will be executed. In proper procedures, a return statement is implied by the end of the procedure body. An explicit return statement therefore appears as an additional (probably exceptional) termination point.
An exit statement is denoted by the symbol \EXIT. It specifies termination of the enclosing loop
statement and continuation with the statement following that loop statement. Exit statements are contextually, although not syntactically associated with the loop statement which contains them.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Procedure declarations}
\label{procedures}
Procedure declarations consist of a procedure heading and a procedure body. The heading specifies the procedure identifier, the formal parameters, and the result type (if any). The body contains declarations and statements. The procedure identifier is repeated at the end of the procedure declaration.
There are two kinds of procedures, namely proper procedures and function procedures. The latter are activated by a function designator as a constituent of an expression, and yield a result that is an operand in the expression. Proper procedures are activated by a procedure call. The function procedure is distinguished in the declaration by indication of the type of its result following the parameter list. Its body must contain a \RETURN\ statement which defines the result of the function procedure.
All constants, variables, types, and procedures declared within a procedure body are local to the procedure. The values of local variables are undefined upon entry to the procedure. Since procedures may be declared as local objects too, procedure declarations may be nested. The call of a procedure within its declaration implies recursive activation.
Objects declared in the environment of the procedure are also visible in those parts of the procedure in which they are not concealed by a locally declared object with the same name.
\begin{lstlisting}[style=ebnf]
ProcedureDeclaration = ProcedureHeading ";" ProcedureBody ident.
ProcedureHeading = PROCEDURE IdentDef [FormalParameters].
ProcedureBody = DeclarationSequence [BEGIN StatementSequence] END.
DeclarationSequence = {CONST {ConstantDeclaration ";"}
| TYPE {TypeDeclaration ";"}
| VAR {VariableDeclaration ";"}}.
{ ProcedureDeclaration ";" | ForwardDeclaration ";"}.
ForwardDeclaration = PROCEDURE "^" IdentDef [FormalParameters].
\end{lstlisting}
A forward declaration serves to allow forward references to a procedure whose actual declaration appears later in the text. The formal parameter lists of the forward declaration and the actual declaration must be identical.
\subsection{Formal parameters}
\label{parameters}
Formal parameters are identifiers which denote actual parameters specified in the procedure call. The correspondence between formal and actual parameters is established when the procedure is called. There are two kinds of parameters, namely value and variable parameters. The kind is indicated in the formal parameter list. Value parameters stand for local variables to which the result of the evaluation of the corresponding actual parameter is assigned as initial value. Variable parameters correspond to actual parameters that are variables, and they stand for these variables. Variable parameters are indicated by the symbol \VAR, value parameters by the absence of the symbol \VAR. A function procedure without parameters must have an empty parameter list. It must be called by a function designator whose actual parameter list is empty too.
Formal parameters are local to the procedure, i.e. their scope is the program text which constitutes the procedure declaration.
\begin{lstlisting}[style=ebnf]
FormalParameters = "(" [FPSection {";" FPSection}] ")" [":" type].
FPSection = [VAR] ident {"," ident} ":" type.
\end{lstlisting}
The type of each formal parameter is specified in the parameter list. For variable parameters, it must be identical to the corresponding actual parameter's type, except in the case of a record, where it must be a base type of the corresponding actual parameter's type. For value parameters, the rule of assignment holds (see \ref{assignment}).
Examples of procedure declarations:
\begin{lstlisting}[style=example]
PROCEDURE add(x : INTEGER; y : INTEGER): INTEGER;
BEGIN
RETURN x + y
END add;
PROCEDURE mult(x : INTEGER; y : INTEGER): INTEGER;
BEGIN
RETURN x * y
END mult;
\end{lstlisting}
\subsection{Type-bound procedures}
Globally declared procedures may be associated with a record type declared in the same module. The procedures are said to be bound to the record type. The binding is expressed by the type of the receiver in the heading of a procedure declaration. The receiver may be either a variable parameter of record type T or a value parameter of type \POINTER\ \TO\ T (where T is a record type). The procedure is bound to the type T and is considered local to it.
\begin{lstlisting}[style=ebnf]
ProcedureHeading = PROCEDURE [Receiver] IdentDef [FormalParameters].
Receiver = "(" [VAR] ident ":" ident ")".
\end{lstlisting}
If a procedure P is bound to a type T0, it is implicitly also bound to any type T1 which is an extension of T0. However, a procedure P' (with the same name as P) may be explicitly bound to T1 in which case it overrides the binding of P.
P' is considered a redefinition of P for T1. The formal parameters of P and P' must match (see App. A).
If P and T1 are exported (see Chapter 4) P' must be exported too.
If v is a designator and P is a type-bound procedure, then v.P denotes that procedure P which is bound to the dynamic type of v. Note, that this may be a different procedure than the one bound to the static type of v. v is passed to P's receiver according to the parameter passing rules specified in \ref{parameters}.
If r is a receiver parameter declared with type T, r.P\^{} denotes the (redefined) procedure P bound to the base type of T.
In a forward declaration of a type-bound procedure the receiver parameter must be of the same type as in the actual procedure declaration. The formal parameter lists of both declarations must be identical.
Examples:
\begin{lstlisting}[style=example]
PROCEDURE (t: Tree) Insert (node: Tree);
VAR p, father: Tree;
BEGIN p := t;
REPEAT father := p;
IF node.key = p.key THEN RETURN END;
IF node.key < p.key THEN p := p.left ELSE p := p.right END
UNTIL p = NIL;
IF node.key < father.key THEN father.left := node ELSE father.right := node END;
node.left := NIL; node.right := NIL
END Insert;
PROCEDURE (t: CenterTree) Insert (node: Tree); (*redefinition*)
BEGIN
WriteInt(node(CenterTree).width);
t.Insert^ (node) (* calls the Insert procedure bound to Tree *)
END Insert;
\end{lstlisting}
\subsection{Predefined Procedures}
\label{predefined}
The following table lists the predefined procedures. Some are generic procedures, i.e. they apply to several types of operands.
\emph{v} stands for a variable, \emph{x} and \emph{n} for expressions, \emph{T} for a basic type or type alias (which can be a compound type).
Function procedures:
\vspace{2mm}
\begin{tabular}{lllp{7cm}}
Name & Argument type & Result type &Function \\
\hline
\ABS(x) & numeric type & type of x & absolute value of x \\ % Runtime
\ASH(x,n) & x, n: integer type & \INTEGER & arithmetic shift ( $x * 2^n$) \\ % Runtime
\CAP(x) & \CHAR & \CHAR & x is letter, corresponding capital letter \\ % Runtime
\CHR(x) & integer type & \CHAR & character with ordinal number x \\ % Runtime
\FLOOR(x) & \REAL & \INTEGER & round down \\ % Runtime
\FLT(x) & \INTEGER & \REAL & identity \\ % Runtime
\LEN(v) & \ARRAY & \INTEGER & length of \ARRAY\ v, else 1 (scalar) for everything else. \\ % Compile time - constant for arrays, strings Runtime
\LONG(x) & any integer type & \INTEGER & identity \\% Compile time
& any real type & \REAL & \\% Compile time
\MAX(T) & T = basic type & T & maximum value of type T\\ % Compile time
& T = \SET\ & \INTEGER & maximum element of a set\\ % Compile time
\MIN(T) & T = basic type & T & minimum value of type T\\ % Compile time
& T = \SET\ & \INTEGER & 0\\ % Compile time
\ODD(x) & integer type & \BOOLEAN & x \MOD\ 2 = 1 \\ % Runtime
\ORD(x) & \CHAR & \INTEGER & ordinal number of x \\ % Runtime
\SIZE(T) & T or v & \INTEGER & size of type T or variable v \\ % Compile time
\SHORT(x) & any integer type & \INTEGER & identity \\% Compile time
& any real type & \REAL & \\% Compile time
\hline
\end{tabular}
\vspace{5mm}
Proper procedures:
\vspace{2mm}
\begin{tabular}{lp{4.5cm}p{4.5cm}}
Name & Argument types & Function \\
\hline
\ASSERT(x) & x: \BOOLEAN & terminate if not x \\
\ASSERT(x, n) & x: \BOOLEAN, n: \INTEGER & terminate if not x, return n to the OS. \\
\COPY(x, v) & x: character array, v: character array & v := x \\ % Runtime
\DEC(v) & integer type & v := v - 1 \\ % Runtime
\DEC(v, n) & v, n: integer type & v := v - n \\ % Runtime
\EXCL(v, x) & v:\SET\ x:\INTEGER & v := v - {x} \\ % Runtime
\HALT(x) & integer constant & terminate program execution \\ % Runtime
\INC(v) & integer type & v := v + 1 \\ % Runtime
\INC(v, n) & v, n: integer type & v := v + n \\ % Runtime
\INCL(v, x) & v:\SET\ x:\INTEGER & v := v + {x} \\ % Runtime
\NEW(v) & pointer to record or array type & allocate v\^{} \\ % Runtime
\NEW(v, $x_0$, ... $x_n$) & v: pointer to open array, $x_i$: integer type & allocate v with lengths $x_0$, ... $x_n$ \\
\NEW(s, n) & s \STRING, n \INTEGER & allocate s, size n. \\ % Runtime
\WriteInt(x) & \INTEGER & print x to standard output. \\ % Runtime
\WriteBoolean(x) & \BOOLEAN & print x to standard output as 0 or 1. \\ % Runtime
\WriteLn() & & print new line character to standard output. \\ % Runtime
\hline
\end{tabular}
\vspace{5mm}
\COPY\ allows the assignment of a string or a character array containing a terminating 0X to another character array. If necessary, the assigned value is truncated to the target length minus one. The target will always contain a terminating 0X.
In \HALT(x), the interpretation of x is left to the underlying system implementation.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Modules}
\label{modules}
A module is a collection of declarations of constants, types, variables, and procedures, and a sequence of statements for the purpose of assigning initial values to the variables. A module typically constitutes a text that is compilable as a unit.
\begin{lstlisting}[style=ebnf]
Module = MODULE ident ";"
[ImportList]
DeclarationSequence
[BEGIN StatementSequence]
END ident "." .
ImportList = IMPORT Import {"," Import} ";".
Import = = [ident ":="] ident.
\end{lstlisting}
The import list specifies the names of the imported modules. If a module A is imported by a module M and A exports an identifier x, then x is referred to as A.x within M. If A is imported as B := A, the object x must be referenced as B.x. This allows short alias names in qualified identifiers. A module must not import itself. Identifiers that are to be exported (i.e. that are to be visible in client modules) must be marked by an export mark in their declaration (see section \ref{declarations}).
The statement sequence following the symbol \BEGIN\ is executed when the module is executed as the entry point in an executable.
\begin{lstlisting}[style=oberon]
MODULE g10; (* ARRAY and RECORD *)
VAR pt : ARRAY 3 OF RECORD
x, y: INTEGER;
END;
BEGIN
FOR i := 0 TO 2 DO
pt[i].x := i;
pt[i].y := i * 3
END;
RETURN pt[1].x + pt[1].y
END g10.
\end{lstlisting}
\section{Standard Library}
\subsection{Math.mod}
Standard functions and values on the \REAL\ floating point type.
\begin{lstlisting}[style=oberon]
DEFINITION Math;
CONST
e* = 2.7182818284590452354D0;
pi* = 3.14159265358979323846D0;
ln2* = 0.693147180559945309417232121458D0;
PROCEDURE Equal*(x : REAL; y : REAL): BOOLEAN;
PROCEDURE sin*(x : REAL): REAL;
PROCEDURE cos*(x : REAL): REAL;
PROCEDURE arctan*(y : REAL): REAL;
PROCEDURE sqrt*(x : REAL): REAL;
PROCEDURE ln*(x : REAL): REAL;
PROCEDURE exp*(x : REAL): REAL;
END Math.
\end{lstlisting}
\subsection{Out.mod}
Standard output.
\begin{lstlisting}[style=oberon]
DEFINITION Out;
PROCEDURE Open*;
PROCEDURE Flush*;
(* Convert 'x' to a string of at least 'n' chars and write it to standard output.
If 'n' is too small it will be extended.
If 'n' is greater then necessary spaces will be added after the number, i.e.
it is left justified. *)
PROCEDURE Int*(x, n : INTEGER);
PROCEDURE Hex*(x, n : INTEGER);
PROCEDURE Real*(x : REAL; n : INTEGER);
PROCEDURE LongReal*(x : REAL; n : INTEGER);
PROCEDURE Set*(x : SET);
PROCEDURE Bool*(x : BOOLEAN);
PROCEDURE Char*(x : CHAR);
PROCEDURE String*(x : STRING);
PROCEDURE Ln*;
END Out.
\end{lstlisting}
\subsection{Strings.mod}
String routines.
\begin{lstlisting}[style=oberon]
DEFINITION Strings;
PROCEDURE Length*(s : STRING): INTEGER;
PROCEDURE Concat*(s1 : STRING; s2 : STRING): STRING;
PROCEDURE ConcatChar*(s : STRING; c : CHAR): STRING;
PROCEDURE AppendChar*(c : CHAR; s : STRING): STRING;
PROCEDURE Compare*(s1 : STRING; s2 : STRING): INTEGER;
END Strings.
\end{lstlisting}
\newpage
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\appendix
\section{Type Rules}
\label{type-rule}
\subsection{Numeric Types}
\begin{itemize}
\item Integer types: \INTEGER.
\item Real types: \REAL.
\item Numeric types: Integer types, Real Types.
\end{itemize}
\subsection{Same types}
Two variables a and b with types $T_a$ and $T_b$ are of the same type if
\begin{itemize}
\item $T_a$ and $T_b$ are both denoted by the same type identifier, or
\item $T_a$ is declared to equal$T_b$ in a type declaration of the form $T_b$ = $T_b$, or
\item a and b appear in the same identifier list in a variable (\VAR), record field, or formal parameter declaration and are not open arrays.
\end{itemize}
\subsection{Equal types}
Two types $T_a$ and $T_b$ are equal if
\begin{itemize}
\item $T_a$ and $T_b$ are the same type, or