home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / Misc / OB3.2D1.DMS / in.adf / Oberon-Bericht_Deutsch < prev    next >
Encoding:
Text File  |  1992-10-15  |  43.8 KB  |  1,059 lines

  1. Die Programmiersprache Oberon (Revidierte Fassung)                      N.Wirth
  2.  
  3. Make it as simple as possible, but not simpler.
  4. A. Einstein.
  5.  
  6.  
  7. 1. Einführung
  8.  
  9. Oberon ist eine aus Modula-2 hervorgegangene universelle Programmiersprache,
  10. deren wesentliche Neuerung das Konzept der Typerweiterung darstellt, welches
  11. die Konstruktion neuer Datentypen auf der Basis bereits existierender
  12. und die Inbezugsetzung dieser Typen untereinander ermöglicht.Dieser Report ist
  13. nicht als Programmierkurs gedacht. Er ist bewußt knapp gehalten und soll als
  14. Referenz für Programmierer, Implementoren und Autoren von Handbüchern dienen.
  15.  
  16. Fehlende Spezifikationen sind meistens beabsichtigt, da sich der betreffende
  17. Sachverhalt entweder aus den gegebenen Sprachregeln ableiten läßt, oder aber
  18. an solchen Stellen bewußt offen gelassen wird, an denen eine endgültige
  19. Festlegung unklug erscheint.
  20.  
  21.  
  22. 2. Syntax
  23.  
  24. Eine Sprache besteht aus einer unendlichen Menge von Sätzen, welche sich gemäß
  25. ihrer Syntax herleiten lassen. Die Sätze der Sprache Oberon nennen wir
  26. Compilationseinheiten (Compilation Units); sie bestehen jeweils aus einer
  27. endlichen Folge vom Symbolen eines endlichen Vokabulars. Das Vokabular der
  28. Sprache Oberon besteht aus Namen (Identifiers), Zahlen (Numbers), Zeichenketten
  29. (Strings), Operatoren (Operators), Begrenzern (Delimiters) und Kommentaren.
  30.  
  31. Die Elemente dieses Vokabulars werden lexikalische Symbole genannt und bestehen
  32. aus Zeichenfolgen. (Man beachte die Unterscheidung zwischen Symbolen und
  33. Zeichen.) Zur Beschreibung der Syntax wird ein erweiterter Backus Naur-
  34. Formalismus (EBNF) verwendet. Eckige Klammern [ und ] bedeuten hierin, daß die
  35. umschlossenen Konstrukte optional sind, und geschweifte Klammern { und }, daß
  36. der dazwischenstehende Satzteil (möglicherweise auch nullmalig) wiederholt
  37. werden darf. Syntaktische Einheiten (Nichtterminalsymbole) werden mit
  38. englischen Begriffen bezeichnet, welche intuitiv die Bedeutung ausdrücken.
  39. Symbole des Sprachvokabulars (Terminalsymbole) werden durch in
  40. Anführungszeichen eingeschlossene Zeichenketten bezeichnet, oder durch Worte in
  41. Großbuchstaben, sogenannte reservierte Worte. Die Syntaktischen Regeln
  42. (Produktionen) sind mit einem Dollarzeichen ($) am linken Zeilenrand markiert.
  43.  
  44.  
  45. 3. Vokabular und Darstellung
  46.  
  47. Die Darstellung von Symbolen durch Zeichen ist mittels des ASCII-Zeichensatzes
  48. definiert. Symbole sind Namen, Zahlen, Zeichenketten, Operatoren, Begrenzer
  49. und Kommentare. Die folgenden lexikalischen Regeln sind einzuhalten:
  50. Leerzeichen und Zeilenbrüche dürfen nicht innerhalb von Symbolen auftreten
  51. (ausgenommen innerhalb von Kommentaren und Leerzeichen in Strings); sie werden
  52. ignoriert, es sei denn, sie wären absolut notwendig, um zwei
  53. aufeinanderfolgende Symbole zu trennen. Groß- und Kleinbuchstaben werden
  54. unterschieden.
  55.  
  56. 1. Namen sind Folgen von Buchstaben und Ziffern. Das erste Zeichen muß ein
  57. Buchstabe sein.
  58.  
  59. $       ident  =  letter {letter | digit}.
  60.  
  61. Beispiele:
  62.  
  63.   x scan   Oberon   GetSymbol   firstLetter
  64.  
  65. 2. Zahlen sind vorzeichenlose Integerzahlen oder reelle Zahlen. Integerzahlen
  66. sind Folgen von Ziffern und können von einem Buchstaben gefolgt werden. Der
  67. Typ einer Zahl ist der Minimaltyp (siehe 6.1), zu dem die Zahl gehört. Folgt
  68. der Ziffernfolge kein Buchstabe, so handelt es sich um eine Zahl in dezimaler
  69. Darstellung. Der nachgestellte Buchstabe H bezeichnet die hexadezimale
  70. Darstellung. Eine reelle Zahl enthält immer einen Dezimalpunkt. Wahlweise
  71. kann auch ein dezimaler Skalierungsfaktor enthalten sein:  Der Buchstabe E
  72. (oder D) wird gesprochen als "mal zehn hoch". Eine reelle Zahl ist vom Typ
  73. REAL, es sei denn, der Skalierungsfaktor wäre D; dann ist die Zahl vom Typ
  74. LONGREAL.
  75.  
  76. $       number =  integer | real.
  77. $       integer  =  digit {digit} | digit {hexDigit} "H" .
  78. $       real  =  digit {digit} "." {digit} [ScaleFactor].
  79. $       ScaleFactor  =  ("E" | "D") ["+" | "-"] digit {digit}.
  80. $       hexDigit  =  digit | "A" | "B" | "C" | "D" | "E" | "F".
  81. $       digit  =  "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9".
  82.  
  83. Beispiele:
  84.  
  85.   1987
  86.   100H    = 256
  87.   12.3
  88.   4.567E8 = 456700000
  89.   0.57712566D-6   = 0.000000577125663.
  90.  
  91. Zeichenkonstanten werden entweder durch ein einzelnes Zeichen in
  92. Anführungszeichen, oder durch die Ordinalzahl des Zeichens in hexadezimaler
  93. Darstellung, gefolgt von dem Buchstaben X, gekennzeichnet.
  94.  
  95. $    CharConstant = """ character """ | digit {hexDigit} "X".
  96.  
  97. 4. Strings sind in Anführungszeichen (") eingeschlossene Zeichenfolgen. Ein
  98. String darf selbst keine Anführungszeichen enthalten. Die Anzahl der Zeichen
  99. eines Strings wird als seine Länge bezeichnet. Strings können Zeichenarrays
  100. zugewiesen werden und mit ihnen verglichen werden (siehe 9.1 und 8.2.4).
  101.  
  102. $ string  =  """ {character} """ .
  103.  
  104. Beispiele:
  105.  
  106.   "OBERON"
  107.   "Don't worry!"
  108.  
  109. 5. Operatoren und Begrenzer sind die nachfolgend aufgeführten speziellen
  110. Zeichen, Zeichenpaare und reservierten Worte. Reservierte Worte bestehen
  111. ausschließlich aus Großbuchstaben und können nicht in der Rolle von Namen
  112. verwendet werden.
  113.  
  114.   +       :=      ARRAY   IS      TO
  115.   -       ^       BEGIN   LOOP    TYPE
  116.   *       =       CASE    MOD     UNTIL
  117.   /       #       CONST   MODULE  VAR
  118.   ~       <       DIV     NIL     WHILE
  119.   &       >       DO      OF      WITH
  120.   .       <=      ELSE    OR
  121.   ,       >=      ELSIF   POINTER
  122.   ;       ..      END     PROCEDURE
  123.   |       :       EXIT    RECORD
  124.   (       )       IF      REPEAT
  125.   [       ]       IMPORT  RETURN
  126.   {       }       IN      THEN
  127.  
  128. 6. Kommentare sind beliebige mit der Klammer (* beginnende und mit *) endende
  129. Zeichenfolgen, welche überall im Programm zwischen zwei Symbolen eingefügt
  130. werden dürfen. Kommentare haben keinen Einfluß auf die Bedeutung eines
  131. Programms.
  132.  
  133.  
  134. 4. Deklarationen und Sichtbarkeitsregeln
  135.  
  136. Jeder Name in einem Programm muß mittels einer Deklaration eingeführt werden,
  137. es sei denn, es handle sich um einen vordefinierten Namen. Deklarationen
  138. dienen auch dazu, bestimmte bleibende Eigenschaften eines Objekts festzulegen,
  139. so z.B., ob es sich um eine Konstante, einen Typ, eine Variable oder eine
  140. Prozedur handelt.Der Name wird verwendet, um sich auf das damit verbundene
  141. Objekt zu beziehen. Dies ist nur innerhalb desjenigen Programmteils möglich,
  142. der im Gültigkeitsbereich der entsprechenden Deklaration liegt. Kein Name darf
  143. sich innerhalb eines einzelnen Gültigkeitsbereichs auf mehr als ein Objekt
  144. beziehen. Ein Gültigkeitsbereich erstreckt sich textuell vom Ort der Deklaration
  145. bis zum Ende des Blocks (Prozedur oder Modul), zu dem die Deklaration gehört;
  146. das Objekt ist somit lokal zu diesem Block. Folgende Zusätze gelten zu dieser
  147. Regel:
  148.  
  149. 1. Wird ein Typ T definiert als POINTER TO T1 (siehe 6.4), dann darf der Name
  150. T1 im Text folgend der Deklaration von T vereinbart werden, aber nur im
  151. gleichen Gültigkeitsbereich.
  152.  
  153. 2. Feldnamen einer Recorddeklaration (siehe 6.3) sind nur innerhalb von Feld-
  154. Bezeichnern gültig. Ein Name mit globalem Gültigkeitsbereich darf bei seiner
  155. Deklaration von einer Exportmarkierung (*) gefolgt sein, die anzeigt, daß er
  156. von seinem Modul exportiert wird. In diesem Falle darf der Name in anderen
  157. Modulen verwendet werden, sofern diese dessen Modul importieren. Dem Namen wird
  158. dann als Präfix der Name, der sein Modul bezeichnet, vorangestellt (siehe
  159. Kap. 11). Präfix und Name werden durch einen Punkt getrennt und gemeinsam
  160. qualifizierter Name genannt.
  161.  
  162. $       qualident = [ident "."] ident.
  163. $       identdef = ident ["*"].
  164.  
  165. Die folgenden Namen sind vordefiniert, ihre Bedeutung wird in den angegebenen
  166. Abschnitten erklärt:
  167.  
  168.   ABS             (10.2)     LEN             (10.2)
  169.   ASH             (10.2)     LONG            (10.2)
  170.   BOOLEAN         (6.1)      LONGINT         (6.1)
  171.   BYTE            (6.1)      LONGREAL        (6.1)
  172.   CAP             (10.2)     MAX             (10.2)
  173.   CHAR            (6.1)      MIN             (10.2)
  174.   CHR             (10.2)     NEW             (6.4)
  175.   DEC             (10.2)     ODD             (10.2)
  176.   ENTIER          (10.2)     ORD             (10.2)
  177.   EXCL            (10.2)     REAL            (6.1)
  178.   FALSE           (6.1)      SET             (6.1)
  179.   HALT            (10.2)     SHORT           (10.2)
  180.   INC             (10.2)     SHORTINT        (6.1)
  181.   INCL            (10.2)     SIZE            (10.2)
  182.   INTEGER         (6.1)      TRUE            (6.1)
  183.  
  184.  
  185. 5. Konstantendeklarationen
  186.  
  187. Eine Konstantendeklaration verbindet einen Namen mit einem konstanten Wert.
  188.  
  189. $       ConstantDeclaration  =  identdef "=" ConstExpression.
  190. $       ConstExpression  =  expression.
  191.  
  192. Ein konstanter Ausdruck kann während des Lesens des Quelltextes berechnet
  193. werden, ohne daß das Programm tatsächlich ausgeführt werden muß. Seine
  194. Operanden sind Konstanten (siehe Kap. 8). Beispiele für Konstanten-
  195. deklarationen sind
  196.  
  197.   N       =       100
  198.   limit   =       2*N -1
  199.   all     =       {0 .. WordSize-1}
  200.  
  201.  
  202. 6. Typdeklarationen
  203.  
  204.  
  205. Ein Datentyp bestimmt die Menge der Werte, welche Variablen dieses Typs
  206. annehmen können, und die anwendbaren Operatoren. Eine Typdeklaration verbindet
  207. einen Namen mit einem Typ; solche Assoziationen können mit Grundtypen (Basic
  208. Types), oder mit strukturierten Typen geschehen. Im letzteren Fall wird
  209. hierdurch auch die Struktur aller Variablen dieses Typs festgelegt und,
  210. implizit, auch die Operatoren, die auf Komponenten solcher Variablen anwendbar
  211. sind. Es gibt zwei Arten von strukturierten Datentypen, nämlich Arrays
  212. (Vektoren, Matrizen) und Records (Verbundtypen), die sich in der Art des
  213. Zugriffs auf die Komponenten unterscheiden.
  214.  
  215. $       TypeDeclaration  =  identdef "=" type.
  216. $       type  =  qualident | ArrayType | RecordType | PointerType | ProcedureType.
  217.  
  218. Beispiele:
  219.  
  220.   Table        =       ARRAY N OF REAL
  221.  
  222.   Tree         =       POINTER TO Node
  223.  
  224.   Node         =       RECORD key: INTEGER;
  225.                         left, right: Tree
  226.                        END
  227.  
  228.   CenterNode   =       RECORD (Node)
  229.                          name: ARRAY 32 OF CHAR;
  230.                          subnode: Tree
  231.                        END
  232.  
  233.   Function*    =       PROCEDURE (x: INTEGER): INTEGER
  234.  
  235. 6.1. Grundtypen
  236.  
  237. Die folgenden Grundtypen sind durch vordefinierte Namen gekennzeichnet. Die
  238. anwendbaren Operatoren werden in Kap. 8.2 beschrieben und die zugehörigen
  239. vordefinierten Funktionen in Kap. 10.2. Die Wertebereiche der Grundtypen sind
  240. wie folgt:
  241.  
  242.   1.    BOOLEAN         die Wahrheitswerte TRUE und FALSE.
  243.   2.    CHAR            die Menge der ASCII-Werte (0X ... 0FFX).
  244.   3.    SHORTINT        die Integerzahlen von MIN(SHORTINT) bis MAX(SHORTINT).
  245.   4.    INTEGER         die Integerzahlen von MIN(INTEGER) bis MAX(INTEGER).
  246.   5.    LONGINT         die Integerzahlen von MIN(LONGINT) bis MAX(LONGINT).
  247.   6.    REAL            die reellen Zahlen von MIN(REAL) bis MAX(REAL).
  248.   7.    LONGREAL        die reellen Zahlen von MIN(LONGREAL) bis MAX(LONGREAL).
  249.   8.    SET             die Menge der Integerzahlen von 0 bis MAX(SET).
  250.   9.    BYTE            (siehe 9.1 und 10.1)
  251.  
  252. Die Typen 3 bis 5 sind Integertypen und 6 und 7 sind reelle Typen. Zusammen
  253. bezeichnen wir sie als numerische Typen. Sie bilden eine Hierarchie; der
  254. mächtigere Typ schließt hierbei jeweils den (Wertebereich des) kleineren
  255. Typ(s) ein.
  256.  
  257.   LONGREAL  J  REAL  J  LONGINT  J  INTEGER  J  SHORTINT
  258.  
  259. 6.2. Arraytypen
  260.  
  261. Ein Array ist eine Datenstruktur, die aus einer festen Anzahl von Elementen des
  262. gleichen Typs, genannt Elementtyp, besteht. Als Länge des Arrays wird die
  263. Anzahl seiner Elemente bezeichnet. Die Elemente eines Arrays werden durch
  264. Indizes ausgewählt. Dies sind Integerzahlen im Wertebereich zwischen 0 und
  265. (Länge minus 1).
  266.  
  267. $       ArrayType  =  ARRAY length {"," length} OF type.
  268. $       length  =  ConstExpression.
  269.  
  270. Eine Deklaration der Form
  271.  
  272.   ARRAY N0, N1, ... , Nk OF T
  273.  
  274. wird betrachtet als Abkürzung der Deklaration
  275.  
  276.   ARRAY N0 OF
  277.     ARRAY N1 OF
  278.       ...
  279.            ARRAY Nk OF T
  280.  
  281.  
  282. Beispiele für Arraytypen:
  283.  
  284.   ARRAY N OF INTEGER
  285.   ARRAY 10, 20 OF REAL
  286.  
  287. 6.3. Recordtypen
  288.  
  289. Ein Record ist eine Datenstruktur, die eine feste Anzahl von Elementen,
  290. möglicherweise unterschiedlicher Typen, beinhaltet. Bei der Deklaration eines
  291. Recordtyps wird für jedes Element, genannt Feld, sein Typ und der Name, der das
  292. Feld auswählt, festgelegt. Der Gültigkeitsbereich dieser Feldnamen ist die
  293. Recorddefinition; sie sind aber auch innerhalb von Feld-Bezeichnern (siehe 8.1)
  294. sichtbar, die sich auf Elemente von Recordvariablen beziehen.
  295.  
  296. $       RecordType  =  RECORD ["(" BaseType ")"] FieldListSequence END.
  297. $       BaseType  =  qualident.
  298. $       FieldListSequence  =  FieldList {";" FieldList}.
  299. $       FieldList  =  [IdentList ":" type].
  300. $       IdentList  =  identdef {"," identdef}.
  301.  
  302. Soll ein Recordtyp exportiert werden, so müssen diejenigen Feldnamen, die
  303. außerhalb des definierenden Moduls sichtbar sein sollen, markiert werden.
  304. Solcherart markierte Felder werden public genannt, nicht markierte hingegen
  305. private. Recordtypen sind erweiterbar, d.h. ein Recordtyp läßt sich als
  306. Erweiterung eines anderen Recordtyps vereinbaren. In den obigen Beispielen ist
  307. CenterNode eine (direkte) Erweiterung von Node, welches wiederum ein (direkter)
  308. Basistyp (Base Type) von CenterNode ist. Genauer gesagt, erweitert CenterNode
  309. den Typ Node um die Felder name und subnode.
  310.  
  311. Definition: Ein Typ T0 erweitert einen Typ T, wenn er gleich T ist, oder wenn
  312. er die direkte Erweiterung einer Erweiterung von T darstellt. Umgekehrt ist
  313. ein Typ T ein Basistyp von T0, falls er gleich T0 ist, oder falls er der
  314. direkte Basistyp eines Basistyps von T0 ist.
  315.  
  316. Beispiele für Recordtypen:
  317.  
  318.   RECORD
  319.     day, month, year: INTEGER
  320.   END
  321.  
  322.   RECORD
  323.     name, firstname: ARRAY 32 OF CHAR;
  324.     age: INTEGER;
  325.     salary: REAL
  326.   END
  327.  
  328. 6.4. Pointertypen
  329.  
  330. Variablen eines Pointertyps (Zeigertyps) P nehmen als Werte Referenzen auf
  331. Variablen eines Typs T an. Man sagt, der Pointertyp P ist an den Typ T
  332. gebunden, und T ist der Pointer-Basistyp von P. T muß ein Record- oder
  333. Arraytyp sein. Pointertypen erben die Erweiterungsbeziehungen ihrer Basistypen.
  334. Wenn ein Typ T0 eine Erweiterung von T ist, und P0 ein an T0 gebundener
  335. Pointertyp, dann ist P0 auch eine Erweiterung von P.
  336.  
  337. $       PointerType  =  POINTER TO type.
  338.  
  339. Ist p eine Variable vom Typ P = POINTER TO T, dann hat der Aufruf der
  340. vordefinierten Prozedur NEW(p) die folgende Wirkung (siehe 10.2):  Im freien
  341. Speicherbereich wird eine Variable vom Typ T alloziert und eine Referenz auf
  342. diese Variable wird der Pointervariablen p zugewiesen. Die Pointervariable p
  343. ist vom Typ P; die referenzierte Variable p^ ist vom Typ T. Kann kein Speicher
  344. reserviert werden, so wird der Pointervariablen p der Wert NIL zugewiesen.
  345. Jeder Pointervariablen darf der Wert NIL zugewiesen werden, welcher auf keine
  346. Variable verweist.
  347.  
  348. 6.5. Prozedurtypen
  349.  
  350. Variablen eines Prozedurtyps T haben als Wert eine Prozedur. Wird
  351. eine Prozedur einer Prozedurvariablen vom Typ T zugewiesen, so müssen die
  352. (Typen der) formalen Parameter von P die gleichen sein, wie die der Parameter
  353. von T. Gleiches gilt für den Typ des Ergebnisses im Fall einer
  354. Funktionsprozedur (siehe 10.1). P darf nicht lokal zu einer anderen Prozedur
  355. vereinbart sein und darf auch keine vordefinierte Prozedur sein. Jeder
  356. Prozedurvariablen darf der Wert NIL zugewiesen werden, welcher auf keine
  357. Prozedur verweist.
  358.  
  359. $       ProcedureType = PROCEDURE [FormalParameters].
  360.  
  361.  
  362. 7. Variablendeklarationen
  363.  
  364. Variablendeklarationen dienen dazu, Variablen einzuführen und sie mit einem
  365. Namen zu verbinden, der im gegebenen Gültigkeitsbereich eindeutig sein muß.
  366. Variablendeklarationen dienen auch dazu, einen Datentyp mit der Variablen zu
  367. assoziieren.
  368.  
  369. $       VariableDeclaration =  IdentList ":" type.
  370.  
  371. Variablen, deren Name in der selben Liste auftreten, haben alle den gleichen
  372. Typ.
  373.  
  374. Beispiele für Variablendeklarationen (siehe Beispiele in Kap. 6):
  375.  
  376.   i, j, k:     INTEGER
  377.   x, y:        REAL
  378.   p, q:        BOOLEAN
  379.   s:           SET
  380.   f:           Function
  381.   a:           ARRAY 100 OF REAL
  382.   w:           ARRAY 16 OF
  383.                   RECORD ch: CHAR;
  384.                      count: INTEGER
  385.                   END
  386.   t:           Tree
  387.  
  388.  
  389. 8. Ausdrücke
  390.  
  391. Ausdrücke (Expressions) beschreiben die Rechenregeln, nach denen die Werte von
  392. Konstanten und die aktuellen Werte von Variablen kombiniert werden, um durch
  393. die Anwendung von Operatoren und Funktionsprozeduren neue Werte zu erhalten.
  394. Ausdrücke bestehen aus Operanden und Operatoren. Spezielle Assoziationen von
  395. Operatoren und Operanden lassen sich durch Klammerung ausdrücken.
  396.  
  397.  
  398. 8.1. Operanden
  399.  
  400. Mit Ausnahme von Mengen und Literalen, d.h. Zahlen und Zeichenketten, werden
  401. Operanden durch Bezeichner (Designators) dargestellt. Ein Bezeichner besteht
  402. aus einem Namen, der sich auf eine zu bezeichnende Konstante, Variable oder
  403. Prozedur bezieht. Dieser Name kann durch einen Modulnamen qualifiziert werden
  404. (siehe Kap. 4 und 11), und von einem Selektor gefolgt werden, falls das
  405. bezeichnete Objekt Element einer Struktur ist.Falls A einen Array bezeichnet,
  406. dann bezieht sich A[E] auf dasjenige Element von A, dessen Index den aktuellen
  407. Wert des Ausdrucks E darstellt. Der Typ von E muß ein Integertyp sein. Ein
  408. Bezeichner der Form A[E1,E2, ... ,En] steht für A[E1][E2]...[En]. Falls p eine
  409. Pointervariable bezeichnet, dann bezieht sich p^ auf diejenige Variable, die
  410. von p referenziert wird. Bezeichnet r einen Record, dann bezieht sich r.f
  411. auf das Feld f des Records r. Falls p einen Pointer bezeichnet, dann bezieht
  412. sich p.f auf das Feld f des Records p^, d.h. der Punkt impliziert die
  413. Dereferenzierung und der Bezeichner steht für p^.f; sinngemäß bezeichnet p[E]
  414. das Element von p^ mit dem Index E.Der Type Guard v(T0), stellt sicher, daß v
  415. vom Typ T0 ist (siehe Kap. 6), d.h. das Programm wird abgebrochen, falls v
  416. nicht vom Typ T0 ist. Ein Type Guard ist anwendbar, falls 1. T0 eine
  417. Erweiterung des deklarierten Typs T von v ist, und falls 2. v ein
  418. Variablenparameter (s.u.) eines Recordtyps ist, oder v eine Pointervariable
  419. darstellt.
  420.  
  421. $       designator  =  qualident {"." ident | "[" ExpList "]" |
  422. $                      "(" qualident ")" | "^" }.
  423. $       ExpList  =  expression {"," expression}.
  424.  
  425. Ist das bezeichnete Objekt eine Variable, so bezieht sich der Bezeichner auf
  426. den aktuellen Wert der Variablen. Ist das Objekt eine Prozedur, dann bezieht
  427. sich ein Bezeichner ohne Parameterliste auf diese Prozedur. Wird er von einer
  428. (möglicherweise leeren) Parameterliste gefolgt, dann impliziert der Bezeichner
  429. eine Aktivierung der Prozedur und steht für den Wert, der aus ihrer Ausführung
  430. resultiert. Die (Typen der) aktuellen Parameter müssen denen der formalen
  431. Parameter entsprechen, so wie sie bei der Definition der Prozedur spezifiziert
  432. wurden (siehe Kap. 10).
  433.  
  434. Beispiele für Bezeichner (siehe Beispiele in Kap. 7):
  435.  
  436.   i                       (INTEGER)
  437.   a[i]                    (REAL)
  438.   w[3].ch                 (CHAR)
  439.   t.key                   (INTEGER)
  440.   t.left.right            (Tree)
  441.   t(CenterNode).subnode   (Tree)
  442.  
  443. 8.2. Operatoren
  444.  
  445. Die Syntax von Ausdrücken unterscheidet zwischen vier Klassen von Operatoren
  446. mit verschiedenen Präzedenzen (Bindungßtärken). Der Operator ~ hat die höchste
  447. Präzedenz, gefolgt von den Multiplikationsoperatoren, Additionsoperatoren und
  448. Relationen. Operatoren der gleichen Präzedenzstufe binden von links nach
  449. rechts.
  450.  
  451. Beispiel:
  452.  
  453.   x-y-z steht für (x-y)-z.
  454.  
  455. $       expression =  SimpleExpression [relation SimpleExpression].
  456. $       relation  =  "=" | "#" | "<" | "<=" | ">" | ">=" | IN | IS.
  457. $       SimpleExpression  =  ["+"|"-"] term {AddOperator term}.
  458. $       AddOperator  =  "+" | "-" | OR .
  459. $       term  =  factor {MulOperator factor}.
  460. $       MulOperator  =  "*" | "/" | DIV | MOD | "&" .
  461. $       factor  =  number | CharConstant | string | NIL | set |
  462. $               designator [ActualParameters] | "(" expression ")" | "~" factor.
  463. $       set  =  "{" [element {"," element}] "}".
  464. $       element  =  expression [".." expression].
  465. $       ActualParameters  =  "(" [ExpList] ")" .
  466.  
  467. Die in Oberon verfügbaren Operatoren sind in den folgenden Tabellen aufgeführt.
  468. Manchmal werden verschiedene Operationen durch das gleiche Operatorsymbol
  469. gekennzeichnet; in diesen Fällen wird die tatsächliche Operation durch den Typ
  470. der Operanden bestimmt.
  471.  
  472. 8.2.1. Logische Operatoren
  473.  
  474. Symbol Ergebnis
  475.  
  476.  OR     logische Disjunktion
  477.   &     logische Konjunktion
  478.   ~     Negation
  479.  
  480. Diese Operatoren sind auf BOOLEAN-Operanden anwendbar und liefern
  481. ein Ergebnis vom Typ BOOLEAN.
  482.  
  483.   p OR q     steht für       "wenn p, dann TRUE, sonst q"
  484.   p & q      steht für       "wenn p, dann q, sonst FALSE"
  485.   ~ p        steht für       "nicht p"
  486.  
  487. 8.2.2. Arithmetische Operatoren
  488.  
  489. Symbol  Ergebnis
  490.  
  491.   +     Summe
  492.   -     Differenz
  493.   *     Produkt
  494.   /     Quotient
  495.  DIV    ganzzahliger Quotient
  496.  MOD    Modulus
  497.  
  498. Die Operatoren +, -, * und / beziehen sich auf Operanden numerischer Typen.
  499. Der Typ des Ergebnisses ist derjenige Operandentyp, der den Typ des anderen
  500. Operanden einschließt, außer bei der Division (/), bei der das Ergebnis
  501. derjenige Realtyp ist, welcher beide Operandentypen einschließt. Als
  502. monadische Operatoren bezeichnen - die Vorzeichenumkehr und + die Identität.
  503. Die Operatoren DIV und MOD sind nur auf ganzzahlige Operanden anwendbar. Sie
  504. sind durch die folgenden Beziehungen zwischen beliebigem x und y>0 definiert:
  505.  
  506.   x  =  (x DIV y) * y  +  (x MOD y)
  507.   0 <=  (x MOD y) < y
  508.  
  509. 8.2.3. Mengenoperatoren
  510.  
  511. Symbol        Ergebnis
  512.  
  513.   +     Vereinigungsmenge
  514.   -     Differenzmenge
  515.   *     Schnittmenge
  516.   /     symmetrische Mengendifferenz
  517.  
  518. Das monadische Minuszeichen bezeichnet das Mengenkomplement von x, d.h. -x
  519. bezeichnet die Menge der Integerzahlen zwischen 0 und MAX(SET), die nicht
  520. Elemente von x sind.
  521.  
  522.   x - y     =  x * (-y)
  523.   x / y     =  (x-y) + (y-x)
  524.  
  525. 8.2.4.  Relationen
  526.  
  527. Symbol Relation
  528.  
  529.   =     gleich
  530.   #     ungleich
  531.   <     kleiner
  532.   <=    kleiner oder gleich
  533.   >     größer
  534.   >=    größer oder gleich
  535.   IN    Mengenzugehörigkeit
  536.   IS    Typtest
  537.  
  538. Relationen liefern Ergebnisse vom Typ BOOLEAN. Die Ordnungsrelationen <, <=, >
  539. und >= sind anwendbar auf numerische Typen, CHAR und Zeichenarrays (Strings).
  540. Die Relationen = und # sind auch auf BOOLEAN, Mengen-, Pointer- und
  541. Prozedurtypen anwendbar. x IN s steht für "x ist Element von s". x muß dabei
  542. ein Integertyp sein und s vom Typ SET. v IS T steht für "v ist vom Typ T" und
  543. wird Typtest genannt. Er ist anwendbar, falls 1. T eine Erweiterung des
  544. deklarierten Typs T0 von v ist, und falls 2. v ein Variablenparameter eines
  545. Recordtyps ist, oder v eine Pointervariable ist. Nehmen wir z.B. an, daß T
  546. eine Erweiterung von T0 darstellt und daß v ein als vom Typ T0 deklarierter
  547. Bezeichner ist, dann bestimmt das Ergebnis des Tests "v IS T", ob die aktuell
  548. bezeichnete Variable (nicht nur vom Typ T0, sondern auch) vom Typ T ist. Der
  549. Wert von "NIL IS T" ist nicht definiert.
  550.  
  551. Beispiele für Ausdrücke (siehe Beispiele in Kap. 7):
  552.  
  553.   1987                    (INTEGER)
  554.   i DIV 3                 (INTEGER)
  555.   ~p OR q                 (BOOLEAN)
  556.   (i+j) * (i-j)           (INTEGER)
  557.   s - {8, 9, 13}          (SET)
  558.   i + x                   (REAL)
  559.   a[i+j] * a[i-j]         (REAL)
  560.   (0<=i) & (i<100)        (BOOLEAN)
  561.   t.key = 0               (BOOLEAN)
  562.   k IN {i .. j-1}         (BOOLEAN)
  563.   t IS CenterNode         (BOOLEAN)
  564.  
  565. 9. Anweisungen
  566.  
  567. Anweisungen (Statements) bezeichnen Aktionen. Wir unterscheiden zwischen
  568. elementaren und strukturierten Anweisungen. Elementare Anweisungen bestehen
  569. nicht selber wieder aus Anweisungen. Es sind dies Wertzuweisungen,
  570. Prozeduraufrufe, und die RETURN- und EXIT-Anweisungen. Strukturierte
  571. Anweisungen beinhalten selbst wieder Anweisungen. Sie werden verwendet, um
  572. Anweisungsfolgen (Statement Sequences), Bedingungen, selektive und wiederholte
  573. Anweisungen zum Ausdruck zu bringen. Ein Anweisung kann auch leer sein; in
  574. diesem Fall bezeichnet sie keine Aktion. Die leere Anweisung dient dem Zweck,
  575. die Interpunktionsregeln in Anweisungsfolgen zu vereinfachen.
  576.  
  577. $       statement  =  [assignment | ProcedureCall |
  578. $             IfStatement | CaseStatement | WhileStatement | RepeatStatement |
  579. $             LoopStatement | WithStatement | EXIT | RETURN [expression] ].
  580.  
  581. 9.1. Wertzuweisungen
  582.  
  583. Eine Wertzuweisung (Assignment) wird verwendet, um den aktuellen Wert einer
  584. Variablen durch einen neuen Wert zu ersetzen, welcher durch einen Ausdruck
  585. angegeben wird. Der Zuweisungsoperator wird geschrieben als ":=" und gesprochen
  586. als "wird zu".
  587.  
  588. $       assignment =  designator ":=" expression.
  589.  
  590. Der Typ des Ausdrucks muß im Typ der Variablen eingeschlossen sein, oder er
  591. muß den Typ der Variablen erweitern. Dabei gelten die folgenden Ausnahmen:
  592.  
  593. 1. Die Konstante NIL darf Variablen eines beliebigen Pointer- oder
  594.    Prozedurtyps zugewiesen werden.
  595.  
  596. 2. Strings können jeder Variablen eines Zeichenarray-Typs zugewiesen werden,
  597.    vorausgesetzt die Länge des Strings ist kleiner als die Länge des Arrays.
  598.  
  599.    Wird ein String s der Länge n einem Array a zugewiesen, dann ist das
  600.    Ergebnis a[i] = s[i] für i = 0..n-1 und a[n] = 0X.
  601.  
  602. 3. Werte vom Typ CHAR und SHORTINT dürfen Variablen vom Typ BYTE zugewiesen
  603.    werden.
  604.  
  605. Beispiele für Wertzuweisungen (siehe auch Beispiele in Kap. 7):
  606.  
  607.   i := 0
  608.   p := i = j
  609.   x := i + 1
  610.   k := log2(i+j)
  611.   F := log2
  612.   s := {2, 3, 5, 7, 11, 13}
  613.   a[i] := (x+y) * (x-y)
  614.   t.key := i
  615.   w[i+1].ch := "A"
  616.  
  617. 9.2. Prozeduraufrufe
  618.  
  619. Ein Prozeduraufruf dient dazu, eine Prozedur zu aktivieren. Der Prozeduraufruf
  620. kann eine Liste von Parametern enthalten, welche anstelle der
  621. korrespondierenden formalen Parameter eingesetzt werden, die bei der Definition
  622. der Prozedur angegeben wurden (siehe Kap. 10). Der Zusammenhang zwischen
  623. aktuellen und formalen Parametern wird durch die Position in der jeweiligen
  624. Liste hergestellt. Es existieren zwei Arten von Parametern:
  625. Variablenparameter und Wertparameter.Im Fall des Variablenparameter muß der
  626. aktuelle Parameter ein Bezeichner sein, der eine Variable repräsentiert.
  627. Bezeichnet er ein Element einer strukturierten Variablen, so wird der Selektor
  628. ausgewertet, wenn die Substitution formaler/aktueller Parameter stattfindet,
  629. d.h. vor der Ausführung der Prozedur. Ist der Parameter ein Wertparameter, dann
  630. muß der korrespondierende aktuelle Parameter ein Ausdruck sein. Dieser
  631. Ausdruck wird vor der Aktivierung der Prozedur evaluiert und das Ergebnis dem
  632. formalen Parameter zugewiesen, der nun eine lokale Variable darstellt (siehe
  633. auch 10.1).
  634.  
  635. $       ProcedureCall  =  designator [ActualParameters].
  636.  
  637. Beispiele für Prozeduraufrufe:
  638.  
  639.   ReadInt(i)  (siehe Kap. 10)
  640.   WriteInt(j*2+1, 6)
  641.   INC(w[k].count)
  642.  
  643. 9.3. Anweisungsfolgen
  644.  
  645. Anweisungsfolgen bezeichnen Sequenzen von Aktionen und werden durch die
  646. entsprechenden Einzelanweisungen, getrennt durch Strichpunkte, spezifiziert.
  647.  
  648. $       StatementSequence  =  statement {";" statement}.
  649.  
  650. 9.4. If-Anweisungen
  651.  
  652. $       IfStatement  =  IF expression THEN StatementSequence
  653. $               {ELSIF expression THEN StatementSequence}
  654. $               [ELSE StatementSequence]
  655. $               END.
  656.  
  657. If-Anweisungen bezeichnen die bedingte Ausführung von Anweisungen. Der
  658. boolesche Ausdruck vor einer bedingten Anweisung wird Guard genannt. Die
  659. einzelnen Guards werden nacheinander in der Reihenfolge ihres Auftretens
  660. ausgewertet, bis die Auswertung eines dieser Guards den Wert TRUE ergibt; dann
  661. wird die damit verbundene Anweisungsfolge ausgeführt. Ist keiner der Guards
  662. erfüllt, dann wird die nach dem Symbol ELSE stehende Anweisungsfolge ausgeführt,
  663. sofern eine vorhanden ist.
  664.  
  665. Beispiel:
  666.  
  667.   IF    (ch >= "A") & (ch <= "Z") THEN ReadIdentifier
  668.   ELSIF (ch >= "0") & (ch <= "9") THEN ReadNumber
  669.   ELSIF ch = 22X THEN ReadString
  670.   ELSE SpecialCharacter
  671.   END
  672.  
  673. 9.5. Case-Anweisungen
  674.  
  675. Case-Anweisungen bezeichnen die Auswahl und Ausführung von Anweisungsfolgen
  676. entsprechend dem Wert eines Ausdrucks. Zuerst wird der Ausdruck berechnet,
  677. dann wird diejenige Anweisungsfolge ausgeführt, deren Liste von Case-Labels
  678. den berechneten Wert enthält. Der Case-Ausdruck und alle Case-Labels müssen
  679. vom gleichen Typ sein, der ein Integertyp oder CHAR sein muß. Case-Labels sind
  680. Konstanten, und kein Wert darf mehr als einmal auftreten. Falls der Wert des
  681. Ausdrucks nicht als Case-Label auftritt, so wird die Anweisungsfolge nach dem
  682. Symbol ELSE ausgeführt, sofern vorhanden; andernfalls liegt ein Laufzeitfehler
  683. vor.
  684.  
  685. $       CaseStatement  =  CASE expression OF case {"|" case}
  686. $                         [ELSE StatementSequence] END.
  687. $       case  = [CaseLabelList ":" StatementSequence].
  688. $       CaseLabelList  =        CaseLabels {"," CaseLabels}.
  689. $       CaseLabels  =   ConstExpression [".." ConstExpression].
  690.  
  691. Beispiel:
  692.  
  693.   CASE ch OF
  694.       "A" .. "Z": ReadIdentifier
  695.     | "0" .. "9": ReadNumber
  696.     | 22X :       ReadString
  697.   ELSE    SpecialCharacter
  698.   END
  699.  
  700. 9.6. While-Anweisungen
  701.  
  702. While-Anweisungen bezeichnen Wiederholungen. Falls der boolesche Ausdruck
  703. (Guard) den Wert TRUE ergibt, so wird die Anweisungsfolge ausgeführt. Die
  704. Berechnung des Ausdrucks und die Ausführung der Anweisungsfolge werden so lange
  705. wiederholt, wie der boolesche Ausdruck das Ergebnis TRUE liefert.
  706.  
  707. $       WhileStatement  =  WHILE expression DO StatementSequence END.
  708.  
  709. Beispiele:
  710.  
  711.   WHILE j > 0 DO
  712.     j := j DIV 2; i := i+1
  713.   END
  714.  
  715.   WHILE (t # NIL) & (t.key # i) DO
  716.     t := t.left
  717.   END
  718.  
  719. 9.7. Repeat-Anweisungen
  720.  
  721. Eine Repeat-Anweisung bezeichnet die wiederholte Ausführung einer
  722. Anweisungsfolge, solange bis eine Bedingung erfüllt ist. Die Anweisungsfolge
  723. wird mindestens einmal ausgeführt.
  724.  
  725. $       RepeatStatement  =  REPEAT StatementSequence UNTIL expression.
  726.  
  727. 9.8. Loop-Anweisungen
  728.  
  729. Eine Loop-Anweisung bezeichnet die wiederholte Ausführung einer
  730. Anweisungsfolge. Dies wird durch die Ausführung einer beliebigen Exit-Anweisung
  731. innerhalb der Anweisungsfolge beendet (siehe auch 9.9).
  732.  
  733. $       LoopStatement  =  LOOP StatementSequence END.
  734.  
  735. Beispiel:
  736.  
  737.   LOOP
  738.     IF t1 = NIL THEN EXIT END ;
  739.     IF k < t1.key THEN t2 := t1.left; p := TRUE
  740.     ELSIF k > t1.key THEN t2 := t1.right; p := FALSE
  741.     ELSE EXIT
  742.     END ;
  743.     t1 := t2
  744.   END
  745.  
  746. Obwohl While- und Repeat-Anweisungen durch eine LOOP-Anweisung mit einer
  747. einzelnen Exit-Anweisung ausgedrückt werden können, wird die Verwendung von
  748. While- und Repeat-Anweisungen in den sehr häufig auftretenden Situation
  749. empfohlen, in denen der Abbruch von einer einzigen Bedingung am Anfang oder
  750. Ende der wiederholten Anweisungsfolge abhängt. Die Loop-Anweisung ist
  751. nützlich, um Fälle mit mehreren Abbruchbedingungen und -punkten auszudrücken.
  752.  
  753. 9.9. Return- und Exit-Anweisungen
  754.  
  755. Eine Return-Anweisung besteht aus dem Symbol RETURN, möglicherweise gefolgt von
  756. einem Ausdruck. Sie zeigt die Beendigung einer Prozedur an, bei
  757. Funktionsprozeduren bestimmt der auf das RETURN folgende Ausdruck das Resultat.
  758. In diesem Fall muß der Typ des Ausdrucks gleich dem Ergebnistyp sein, wie er
  759. im Prozedurkopf angegeben wurde (siehe Kap.10).Funktionsprozeduren verlangen
  760. die Anwesenheit einer Return-Anweisung, welche den Resultatwert angibt. Mehrere
  761. Return-Anweisungen sind erlaubt, obwohl nur eine davon ausgeführt wird. Bei
  762. reinen Prozeduren impliziert das Ende des Prozedurkörpers ein Return-Anweisung.
  763. Eine ausdrückliche Return-Anweisung erscheint daher als zusätzlicher
  764. (möglicherweise außerordentlicher) Abschlußpunkt der Prozedur. Eine
  765. Exit-Anweisung besteht aus dem Symbol EXIT. Sie bestimmt die Beendigung der
  766. umschließenden Loop-Anweisung. Das Programm wird mit derjenigen Anweisung
  767. fortgesetzt, die auf die Loop-Anweisung folgt. Exit-Anweisungen sind textuell,
  768. aber nicht syntaktisch, an diejenige Loop-Anweisung gebunden, in der sie
  769. enthalten sind.
  770.  
  771. 9.10. With-Anweisungen
  772.  
  773. Eine Pointervariable oder ein Variablenparameter mit Recordstruktur vom Typ T0
  774. darf im Kopf einer With-Anweisung mit einem Typ T angegeben werden, der eine
  775. Erweiterung des Typs T0 darstellt. Dann wird diese Variable innerhalb der
  776. With-Anweisung so behandelt, als ob sie vom Typ T vereinbart wäre. Die
  777. With-Anweisung übernimmt eine Rolle ähnlich dem Type Guard, nur daß sie diesen
  778. Guard über eine Anweisungsfolge ausdehnt. Sie kann deshalb als ein regionaler
  779. Type Guard betrachtet werden.
  780.  
  781. $       WithStatement  =  WITH qualident ":" qualident DO StatementSequence END.
  782.  
  783. Beispiel:
  784.  
  785.   WITH t: CenterNode DO name := t.name; L := t.subnode END
  786.  
  787.  
  788. 10. Prozedurdeklarationen
  789.  
  790. Prozedurdeklarationen bestehen aus einem Prozedurkopf (Procedure Heading) und
  791. einem Prozedurkörper (Procedure Body). Der Prozedurkopf bestimmt den
  792. Prozedurnamen, die formalen Parameter und den Typ des Ergebnisses (sofern
  793. vorhanden). Der Prozedurkörper beinhaltet Deklarationen und Anweisungen. Der
  794. Prozedurname wird am Ende der Prozedurdeklaration wiederholt.Es gibt zwei Arten
  795. von Prozeduren, reine Prozeduren und Funktionsprozeduren. Letztere werden
  796. durch Funktionsbezeichner als Bestandteile von Ausdrücken aktiviert und liefern
  797. Ergebnisse, welche als Operanden in diese Ausdrücke einfließen. Reine
  798. Prozeduren werden durch Prozeduraufrufe aktiviert. Funktionsprozeduren werden
  799. bei der Deklaration durch die Angabe eines Ergebnistyps nach der Parameterliste
  800. unterschieden; ihr Prozedurkörper muß eine RETURN-Anweisung enthalten, welche
  801. das Ergebnis bestimmt.Alle Konstanten, Variablen, Typen und Prozeduren, die
  802. innerhalb des Prozedurkörpers vereinbart werden, sind lokal zu dieser Prozedur.
  803. Die Werte lokaler Variablen sind bei Eintritt in die Prozedur unbestimmt. Da
  804. auch Prozeduren als lokale Objekte vereinbart werden dürfen, kann man
  805. Prozedurdeklarationen ineinander verschachteln.Zusätzlich zu den formalen
  806. Parametern und lokal vereinbarten Objekten sind auch die in der Umgebung der
  807. Prozedur vereinbarten Objekte innerhalb der Prozedur sichtbar (mit Ausnahme
  808. derjenigen Objekte, die den gleichen Namen tragen, wie lokale Objekte). Die
  809. Verwendung des Prozedurnamens als Aufruf innerhalb ihrer Deklaration impliziert
  810. eine rekursive Aktivierung der Prozedur.
  811.  
  812. $       ProcedureDeclaration  =  ProcedureHeading ";" ProcedureBody ident.
  813. $       ProcedureHeading  =  PROCEDURE ["*"] identdef [FormalParameters].
  814. $       ProcedureBody  =  DeclarationSequence [BEGIN StatementSequence] END.
  815. $       ForwardDeclaration  =  PROCEDURE "^" identdef [FormalParameters].
  816. $       DeclarationSequence  =  {CONST {ConstantDeclaration ";"} |
  817. $           TYPE {TypeDeclaration ";"} | VAR {VariableDeclaration ";"}}
  818. $           {ProcedureDeclaration ";" | ForwardDeclaration ";"}.
  819.  
  820. Eine Vorausdeklaration erlaubt es, sich auf eine Prozedur zu beziehen, die erst
  821. später im Text vollständig vereinbart wird. Die tatsächliche Deklaration, die
  822. den Prozedurkörper bestimmt, muß die gleichen Parameter und den gleichen
  823. Ergebnistyp (sofern vorhanden) wie die Vorausdeklaration besitzen, und muß im
  824. gleichen Gültigkeitsbereich liegen. Ein dem PROCEDURE-Symbol folgender Stern
  825. ist ein Hinweis an den Compiler, der anzeigt, daß die Prozedur als Parameter
  826. verwendbar ist und Variablen kompatibler Prozedurtypen zugewiesen werden kann.
  827.  
  828. 10.1. Formale Parameter
  829.  
  830. Formale Parameter sind Namen, welche die aktuellen Parameter einer Prozedur
  831. repräsentieren. Der Zusammenhang zwischen aktuellen und formalen Parametern
  832. wird beim Aufruf der Prozedur hergestellt. Es gibt zwei Arten von Parametern,
  833. Wertparameter (Value Parameters) und Variablenparameter (Variable Parameters).
  834. Die jeweilige Art wird in der formalen Parameterliste angegeben. Wertparameter
  835. stehen für lokale Variablen, denen das Ergebnis der Auswertung des
  836. korrespondierenden aktuellen Parameter als Anfangswert zugewiesen wird.
  837. Variablenparameter entsprechen aktuellen Parametern, welche Variablen sind, und
  838. repräsentieren diese. Variablenparameter werden durch das Symbol VAR
  839. gekennzeichnet, Wertparameter durch dessen Abwesenheit. Funktionsprozeduren
  840. ohne Parameter müssen eine leere Parameterliste besitzen und müssen mit einem
  841. Funktionsbezeichner aufgerufen werden, dessen aktuelle Parameterliste ebenfalls
  842. leer ist. Formale Parameter sind lokal zur Prozedur, d.h. ihr
  843. Gültigkeitsbereich ist der Text der Prozedurdeklaration.
  844.  
  845. $       FormalParameters =  "(" [FPSection {";" FPSection}] ")" [":" qualident].
  846. $       FPSection  =  [VAR] ident  {"," ident} ":" FormalType.
  847. $       FormalType  =  {ARRAY OF} qualident.
  848.  
  849. Der Typ jedes formalen Parameters wird in der Parameterliste angegeben. Bei
  850. Variablenparametern muß er identisch dem Typ des entsprechenden aktuellen
  851. Parameters sein, außer im Fall eines Records; hier muß er ein Basistyp des
  852. Typs des entsprechenden aktuellen Parameters sein. Bei Wertparametern gelten
  853. die Regeln der Zuweisungskompatibilität (siehe 9.1). Wird ein Parametertyp
  854. angegeben als ARRAY OF Tdann nennt man den Parameter einen Open Array Parameter
  855. und der entsprechende aktuelle Parameter darf irgend ein Array vom Elementtyp T
  856. sein.Im Falle eines Parameters vom formalen Typ BYTE darf der entsprechende
  857. aktuelle Parameter auch vom Typ CHAR oder SHORTINT sein. Ist der Typ des
  858. formalen Variablenparameters ein ARRAY OF BYTE, dann sind aktuelle Parameter
  859. jeden beliebigen Typs zugelassen. Spezifiziert der formale Parameter einen
  860. Prozedurtyp, dann muß der korrespondierende aktuelle Parameter entweder eine
  861. auf der Stufe 0 vereinbarte Prozedur sein, oder eine Variable (oder ein
  862. Parameter) von diesem Prozedurtyp sein. Eine vordefinierte Prozedur ist an
  863. dieser Stelle nicht erlaubt. Das Ergebnis einer Prozedur darf weder ein Record
  864. noch ein Array sein.
  865.  
  866. Beispiele für Prozedurdeklarationen:
  867.  
  868.   PROCEDURE ReadInt(VAR x: INTEGER);
  869.     VAR i : INTEGER; ch: CHAR;
  870.   BEGIN i := 0; Read(ch);
  871.      WHILE ("0" <= ch) & (ch <= "9") DO
  872.          i := 10*i + (ORD(ch)-ORD("0")); Read(ch)
  873.      END ;
  874.      x := i
  875.   END ReadInt
  876.  
  877.   PROCEDURE WriteInt(x: INTEGER);  (* 0 <= x < 10^5 *)
  878.     VAR i: INTEGER;
  879.         buf: ARRAY 5 OF INTEGER;
  880.   BEGIN i := 0;
  881.      REPEAT buf[i] := x MOD 10;  x := x DIV 10;  INC(i) UNTIL x = 0;
  882.      REPEAT DEC(i); Write(CHR(buf[i] + ORD("0"))) UNTIL i = 0
  883.   END WriteInt
  884.  
  885.   PROCEDURE log2(x: INTEGER): INTEGER;
  886.     VAR y: INTEGER;  (*assume x>0*)
  887.   BEGIN y := 0;
  888.      WHILE x > 1 DO x := x DIV 2; INC(y) END ;
  889.      RETURN y
  890.   END log2
  891.  
  892. 10.2. Vordefinierte Prozeduren
  893.  
  894. Die folgende Tabelle zeigt die vordefinierten Prozeduren auf. Einige davon
  895. sind generische Prozeduren, d.h. sie sind auf mehrere Operandentypen anwendbar.
  896. v steht für eine Variable, x und n stehen für Ausdrücke und T für irgendeinen
  897. Typ.
  898.  
  899. Funktionsprozeduren:
  900.  
  901. Name         Argumenttyp       Ergebnistyp   Funktion
  902.  
  903. ABS(x)       numerischer Typ   Typ von x     Absolutwert
  904. ODD(x)       Integertyp        BOOLEAN       x MOD 2 = 1
  905. CAP(x)       CHAR              CHAR          entsprechender Großbuchstabe
  906. ASH(x, n)    x, n: Integertyp  LONGINT       x * 2n, arithmetischer Shift
  907. LEN(v, n)    v: Array          LONGINT       Länge von v in Dimension n
  908.              n: Integertyp                   LEN(v) ist äquivalent zu
  909.                                              LEN(v, 0)
  910. SIZE(T)      beliebiger Typ    Integertyp    Anzahl der von T beanspruchten Bytes
  911. MAX(T)       T = Grundtyp      T             Maximalwert des Typs T
  912.              T = SET           INTEGER       größtes Element der Menge
  913. MIN(T)       T = Grundtyp      T             Minimalwert des Typs T
  914.              T = SET           INTEGER       0
  915.  
  916. Prozeduren zur Typkonversion:
  917.  
  918. Name         Argumenttyp       Ergebnistyp   Funktion
  919.  
  920. ORD(x)       CHAR, BYTE        INTEGER       Ordinalzahl von x
  921. CHR(x)       Integertyp, BYTE  CHAR          Zeichen mit dem Ordinalzahl x
  922. SHORT(x)     LONGINT           INTEGER       Identität
  923.              INTEGER           SHORTINT
  924.              LONGRAL           REAL          (Beschneidung des Wertes möglich)
  925. LONG(x)      SHORTINT          INTEGER       Identität
  926.              INTEGER           LONGINT
  927.              REAL              LONGREAL
  928. ENTIER(x)    reeller Typ       LONGINT       größte Integerzahl <= x
  929.                                              Anmerkung: ENTIER(i/j) = i DIV j
  930.  
  931. Reine Prozeduren:
  932.  
  933. Name         Argumenttyp                     Funktion
  934.  
  935. INC(v)       Integertyp                      v := v+1
  936. INC(v, x)    Integertyp                      v := v+x
  937. DEC(v)       Integertyp                      v := v-1
  938. DEC(v, x)    Integertyp                      v := v-x
  939. INCL(v, x)   v: SET; x: Integertyp           v := v + {x}
  940. EXCL(v, x)   v: SET; x: Integertyp           v := v - {x}
  941. COPY(x, v)   x: Zeichenarray, String         v := x
  942.              v: Zeichenarray
  943. NEW(v)       Pointertyp                      Speicher für v^ reservieren
  944. HALT(x)      Integerkonstante                Programmlauf beenden
  945.  
  946. Der zweite Parameter von INC und DEC kann entfallen, dann wird jeweils der Wert
  947. 1 verwendet. Die Interpretation des Parameters x in HALT(x) wird der
  948. jeweiligen Systemimplementation überlassen.
  949.  
  950.  
  951. 11. Module
  952.  
  953. Ein Modul besteht aus einer Sammlung von Konstanten-, Typen-, Variablen- und
  954. Prozedurdeklarationen und aus einer Folge von Anweisungen zur Initialisierung
  955. von Variablen. Ein Modul besteht typischerweise aus einem Text, der als
  956. Einheit kompilerbar ist.
  957.  
  958. $       module  = MODULE ident ";"  [ImportList] DeclarationSequence
  959. $           [BEGIN StatementSequence] END ident "." .
  960. $       ImportList  =  IMPORT import {"," import} ";" .
  961. $       import  =  ident [":=" ident].
  962.  
  963. Die Importliste gibt diejenigen Module an, deren Klient das aktuelle Modul ist.
  964. Wird ein Name x von einem Modul M exportiert, und wird M in der Importliste
  965. eines anderen Moduls aufgeführt, dann wird x dort als M.x referenziert. Falls
  966. in der Importliste die Form "M := M1" verwendet wird, so wird auf ein im Modul
  967. M1 deklariertes Objekt x als M.x zugegriffen.Namen, die in einem Klientenmodul
  968. sichtbar sein sollen, also außerhalb des vereinbarenden Moduls, müssen bei
  969. ihrer Deklaration mit einer Exportmarke versehen werden. Die Anweisungsfolge
  970. nach dem Symbol BEGIN wird ausgeführt, wenn das Modul geladen wird. Einzelne
  971. (parameterlose) Prozeduren können anschließend vom System aktiviert werden,
  972. sie dienen als Kommandos (Commands).
  973.  
  974. Beispiel:
  975.  
  976.         MODULE Out;
  977.         (*exported procedures: Write, WriteInt, WriteLn*)
  978.         IMPORT Texts, Oberon;
  979.  
  980.         VAR W: Texts.Writer;
  981.  
  982.         PROCEDURE Write*(ch: CHAR);
  983.         BEGIN
  984.           Texts.Write(W, ch)
  985.         END;
  986.  
  987.         PROCEDURE WriteInt*(x, n: LONGINT);
  988.         VAR
  989.           i: INTEGER;
  990.           a: ARRAY 16 OF CHAR;
  991.         BEGIN
  992.           i := 0;
  993.           IF x < 0 THEN Texts.Write(W, "-"); x := -x END ;
  994.           REPEAT a[i] := CHR(x MOD 10 + ORD("0")); x := x DIV 10; INC(i) UNTIL x = 0;
  995.           REPEAT Texts.Write(W, " "); DEC(n) UNTIL n <= i;
  996.           REPEAT DEC(i); Texts.Write(W, a[i]) UNTIL i = 0
  997.         END WriteInt;
  998.  
  999.         PROCEDURE WriteLn*;
  1000.         BEGIN
  1001.           Texts.WriteLn(W);
  1002.           Texts.Append(Oberon.Log, W.buf)
  1003.         END WriteLn;
  1004.  
  1005.         BEGIN
  1006.           Texts.OpenWriter(W)
  1007.         END Out.
  1008.  
  1009.  
  1010. Anhang: Das Modul SYSTEM
  1011.  
  1012. Das Modul SYSTEM enthält bestimmte Prozeduren, welche notwendig sind, um
  1013. "low-level"-Operationen zu programmieren, die sich direkt auf Objekte beziehen,
  1014. die für einen bestimmten Computer oder ein spezielles Betriebssystem spezifisch
  1015. sind. Dies beinhaltet beispielsweise Möglichkeiten zum Zugriff auf
  1016. Peripheriegeräte, die direkt von diesem Computer kontrolliert werden und
  1017. Möglichkeiten, die Typkompatibilitätsregeln zu durchbrechen, die sonst aufgrund
  1018. der Sprachdefinition aufgezwungen werden. Es wird empfohlen, die Verwendung
  1019. des Moduls SYSTEM auf spezielle Module (sogenannte Low-Level-Module) zu
  1020. beschränken. Derartige Module sind naturgemäß nicht portabel, aber leicht am
  1021. Namen SYSTEM in der Importliste erkennbar. Die folgenden Spezifikationen
  1022. gelten für die ETH-Implementation für den NS32000-Prozessor. Die im Modul
  1023. SYSTEM enthaltenen Prozeduren sind in den folgenden Tabellen aufgeführt.
  1024. Sie entsprechen einzelnen Prozessorinstruktionen, die als Inline-Code
  1025. kompiliert werden. Für weitere Details wird der Leser auf das
  1026. Prozessorhandbuch verwiesen. v steht für eine Variable, x, y, a und n stehen
  1027. für Ausdrücke und T steht für einen Typ.
  1028.  
  1029. Funktionsprozeduren:
  1030.  
  1031. Name      Argumenttyp             Ergebnistyp     Funktion
  1032.  
  1033. ADR(v)    beliebig                LONGINT         Adresse der Variablen v
  1034. BIT(a, n) a: LONGINT              BOOLEAN         Mem[a][n]
  1035.           n: Integertyp
  1036. CC(n)     n: Integerkonstante     BOOLEAN         Condition Code n (0 <= n < 16)
  1037. LSH(x,
  1038.  
  1039. LSH(x,n)  x, n: Integertyp        LONGINT         logischer Shift
  1040. ROT(x,n)  x, n: Integertyp        LONGINT         Rotation
  1041. VAL(T,x)  T, x: beliebiger Typ    T               x interpretiert als vom Typ T
  1042.  
  1043.  
  1044. Reine Prozeduren:
  1045.  
  1046. Name            Argumenttyp               Funktion
  1047.  
  1048. GET(a, v)       a: LONGINT;               v := Mem[a]
  1049.                 v: beliebiger Grundtyp
  1050. PUT(a, x)       a: LONGINT;               Mem[a] := x
  1051.                 x: beliebiger Grundtyp
  1052. MOVE(a0, a1, n) a0, a1, n: Integertyp     Mem[a1+i] := Mem[a0+i], i = 0..n-1
  1053. NEW(v, n)       v: beliebiger Pointertyp  reserviert einen Speicherblock von n
  1054.                 n: Integertyp             Bytes und übergibt seine Adresse an v
  1055.  
  1056.  
  1057. Übersetzung aus dem Englischen: Michael Franz
  1058.  
  1059.