From 568ba8896a626add47166c2c60095cfe3e81b584 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Mon, 12 Apr 2021 16:28:16 -0400 Subject: [PATCH] updated spec based on current implementation --- Oberon.html | 131 ++++++++++++++++++++++++---------------------------- 1 file changed, 61 insertions(+), 70 deletions(-) diff --git a/Oberon.html b/Oberon.html index db7db86..673b649 100644 --- a/Oberon.html +++ b/Oberon.html @@ -1,7 +1,7 @@ - + - + The Programming Language Oberon @@ -149,24 +149,23 @@

Table of Contents

-
    -
  1. Preface
  2. -
  3. History and introduction
  4. -
  5. Syntax
  6. -
  7. Vocabulary
  8. -
  9. Declarations and scope rules
  10. -
  11. Constant declarations
  12. -
  13. Type declarations
  14. -
  15. Variable declarations
  16. -
  17. Expressions
  18. -
  19. Statements
  20. -
  21. Procedure declarations
  22. -
  23. Modules
  24. +
-

Appendix: The Syntax of Oberon

- -

Preface

+

Preface

This document started as a direct copy of Niklaus Wirth's Oberon07 specification that has been incrementally revised and refactored to create an essentially new language. Most of the changes are cosmetic and serve to "modernize" the language. The changes so far ar as follows:

-

+

-

+

1. Introduction

@@ -359,7 +358,7 @@ digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9". identdef = ident ["*"]. -

The following identifiers are predefined; their meaning is defined in section 6.1 (types) or 10.2 (procedures):

+

The following identifiers are predefined; their meaning is defined in section 6.1 (types) or 10.2 (procedures):

@@ -376,7 +375,7 @@ identdef = ident ["*"]. - + @@ -400,7 +399,7 @@ identdef = ident ["*"]. ConstExpression = expression. -

A constant expression can be evaluated by a mere textual scan without actually executing the program. Its operands are constants (see Ch. 8). Examples of constant declarations are:

+

A constant expression can be evaluated by a mere textual scan without actually executing the program. Its operands are constants (see Ch. 8). Examples of constant declarations are:

N = 100
 
@@ -408,9 +407,6 @@ ConstExpression = expression.
limit = 2*N - 1
 
-
all = {0 .. WordSize - 1}
-
-
name = "Oberon"
 
@@ -424,7 +420,7 @@ type = qualident | ArrayType | RecordType | PointerType | ProcedureType.

Examples:

-
Table = ARRAY N OF REAL
+        
Table = ARRAY N OF Real
 
Tree = POINTER TO Node
@@ -436,7 +432,7 @@ END
 
CenterNode = RECORD (Node)
-    name: ARRAY 32 OF CHAR;
+    name: ARRAY 32 OF Char;
     subnode: Tree
 END
 
@@ -446,7 +442,7 @@ END

6.1. Basic types

-

The following basic types are denoted by predeclared identifiers. The associated operators are defined in 8.2, and the predeclared function procedures in 10.2. The values of a given basic type are the following:

+

The following basic types are denoted by predeclared identifiers. The associated operators are defined in 8.2, and the predeclared function procedures in 10.2. The values of a given basic type are the following:

@@ -495,12 +491,12 @@ length = ConstExpression.
ARRAY N OF Int
 
-
ARRAY 10, 20 OF REAL
+        
ARRAY 10, 20 OF Real
 

6.3. Record types

-

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 8.1) referring to elements of record variables.

+

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 8.1) referring to elements of record variables.

RecordType = RECORD ["(" BaseType ")"] [FieldListSequence] END.
 BaseType = qualident.
@@ -522,9 +518,9 @@ END
 
RECORD
-    name, firstname: ARRAY 32 OF CHAR;
+    name, firstname: ARRAY 32 OF Char;
     age: Int;
-    salary: REAL
+    salary: Real
 END
 
@@ -537,11 +533,11 @@ END

If a type P is defined as POINTER TO T, the identifier T can be declared textually following the declaration of P, but [if so] it must lie within the same scope.

-

If p is a variable of type P = POINTER TO T, then a call of the predefined procedure NEW(p) has the following effect (see 10.2): A variable of type T is allocated in free storage, and a pointer to it is assigned to p. This pointer p is of type P and the referenced variable p^ is of type T. Failure of allocation results in p obtaining the value NIL. Any pointer variable may be assigned the value NIL, which points to no variable at all.

+

If p is a variable of type P = POINTER TO T, then a call of the predefined procedure NEW(p) has the following effect (see 10.2): A variable of type T is allocated in free storage, and a pointer to it is assigned to p. This pointer p is of type P and the referenced variable p^ is of type T. Failure of allocation results in p obtaining the value NIL. Any pointer variable may be assigned the value NIL, which points to no variable at all.

6.5. Procedure types

-

Variables of a procedure type T have a procedure (or NIL) as value. If a procedure P is assigned to a procedure variable of type T, the (types of the) formal parameters of P must be the same as those indicated in the formal parameters of T. The same holds for the result type in the case of a function procedure (see 10.1). P must not be declared local to another procedure, and neither can it be a standard procedure.

+

Variables of a procedure type T have a procedure (or NIL) as value. If a procedure P is assigned to a procedure variable of type T, the (types of the) formal parameters of P must be the same as those indicated in the formal parameters of T. The same holds for the result type in the case of a function procedure (see 10.1). P must not be declared local to another procedure, and neither can it be a standard procedure.

ProcedureType = PROCEDURE [FormalParameters].
 
@@ -553,27 +549,25 @@ END
VariableDeclaration = IdentList ":" type.
 
-

Variables whose identifiers appear in the same list are all of the same type. Examples of variable declarations (refer to examples in Ch. 6):

+

Variables whose identifiers appear in the same list are all of the same type. Examples of variable declarations (refer to examples in Ch. 6):

i, j, k: Int
 
-
x, y: REAL
+        
x, y: Real
 
-
p, q: BOOLEAN
-
-
s: SET
+        
p, q: Bool
 
f: Function
 
-
a: ARRAY 100 OF REAL
+        
a: ARRAY 100 OF Real
 
w: ARRAY 16 OF
-    RECORD ch: CHAR;
+    RECORD ch: Char;
         count: Int
     END
 
@@ -587,7 +581,7 @@ END

8.1. Operands

-

With the exception of sets and literal constants, i.e. numbers and strings, operands are denoted by designators. A designator consists of an identifier referring to the constant, variable, or procedure to be designated. This identifier may possibly be qualified by module identifiers (see Ch. 4 and 11), and it may be followed by selectors, if the designated object is an element of a structure.

+

With the exception of sets and literal constants, i.e. numbers and strings, operands are denoted by designators. A designator consists of an identifier referring to the constant, variable, or procedure to be designated. This identifier may possibly be qualified by module identifiers (see Ch. 4 and 11), and it may be followed by selectors, if the designated object is an element of a structure.

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 of type Int. A designator of the form A[E1, E2, ... , En] stands for A[E1][E2] ... [En]. If p designates a pointer variable, p^ denotes the variable which is referenced by p. If r designates a record, then r.f denotes the field f of r. If p designates a pointer, p.f denotes the field f of the record p^, i.e. the dot implies dereferencing and p.f stands for p^.f.

@@ -603,9 +597,9 @@ selector = "." ident | "[" ExpList "]" | "^" | "(" qualident ")". ExpList = expression {"," expression}.
-

If the designated object is a variable, then the designator refers to the variable's current value. If the object is a procedure, a designator without parameter list refers to that procedure. If it is followed by a (possibly empty) parameter list, the designator implies an activation of the procedure and stands for the value resulting from its execution. The (types of the) actual parameters must correspond to the formal parameters as specified in the procedure's declaration (see Ch. 10).

+

If the designated object is a variable, then the designator refers to the variable's current value. If the object is a procedure, a designator without parameter list refers to that procedure. If it is followed by a (possibly empty) parameter list, the designator implies an activation of the procedure and stands for the value resulting from its execution. The (types of the) actual parameters must correspond to the formal parameters as specified in the procedure's declaration (see Ch. 10).

-

Examples of designators (see examples in Ch. 7):

+

Examples of designators (see examples in Ch. 7):

Byte Char
Decrement Floor
@@ -615,11 +609,11 @@ ExpList = expression {"," expression}. - + - + @@ -673,7 +667,7 @@ ActualParameters = "(" [ExpList] ")" .
a[i](REAL)(Real)
w[3].ch(CHAR)(Char)
t.key
-

These operators apply to BOOLEAN operands and yield a BOOLEAN result.

+

These operators apply to Bool operands and yield a Bool result.

@@ -776,7 +770,7 @@ ActualParameters = "(" [ExpList] ")" .
-

Relations are Boolean. The ordering relations <, <=, >, >= apply to the numeric types, CHAR, and character arrays. The relations = and # also apply to the types BOOLEAN, SET, and to pointer and procedure types.

+

Relations are Boolean. The ordering relations <, <=, >, >= apply to the numeric types, Char, and character arrays. The relations = and # also apply to the types Bool, SET, and to pointer and procedure types.

v IS T stands for “v is of type T” and is called a type test. It is applicable, if

@@ -787,7 +781,7 @@ ActualParameters = "(" [ExpList] ")" .

Assuming, for instance, that T is an extension of T0 and that v is a designator declared of type T0, then the test v IS T determines whether the actually designated variable is (not only a T0, but also) a T. The value of NIL IS T is undefined.

-

Examples of expressions (refer to examples in Ch. 7):

+

Examples of expressions (refer to examples in Ch. 7):

@@ -801,7 +795,7 @@ ActualParameters = "(" [ExpList] ")" . - + @@ -809,19 +803,19 @@ ActualParameters = "(" [ExpList] ")" . - + - + - + - +
~p OR q(BOOLEAN)(Bool)
(i+j) * (i-j)
a[i+j] * a[i-j](REAL)(Real)
(0<=i) & (i<100)(BOOLEAN)(Bool)
t.key = 0(BOOLEAN)(Bool)
t IS CenterNode(BOOLEAN)(Bool)
@@ -847,12 +841,12 @@ ActualParameters = "(" [ExpList] ")" .
  1. The constant NIL can be assigned to variables of any pointer or procedure type.
  2. -
  3. Strings can be assigned to any array of characters, provided the number of characters in the string is less than that of the array. (A null character is appended). Single-character strings can also be assigned to variables of type CHAR.
  4. +
  5. Strings can be assigned to any array of characters, provided the number of characters in the string is less than that of the array. (A null character is appended). Single-character strings can also be assigned to variables of type Char.
  6. In the case of records, the type of the source must be an extension of the type of the destination.
  7. An open array may be assigned to an array of equal base type.
-

Examples of assignments (see examples in Ch. 7):

+

Examples of assignments (see examples in Ch. 7):

i := 0
 
@@ -860,7 +854,7 @@ ActualParameters = "(" [ExpList] ")" .
p := i = j
 
-
x := FLT(i + 1)
+        
x := AsFloat(i + 1)
 
k := (i + j) DIV 2
@@ -869,9 +863,6 @@ ActualParameters = "(" [ExpList] ")" .
         
f := log2
 
-
s := {2, 3, 5, 7, 11, 13}
-
-
a[i] := (x+y) * (x-y)
 
@@ -883,9 +874,9 @@ ActualParameters = "(" [ExpList] ")" .

9.2. 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 Ch. 10). 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.

+

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 Ch. 10). 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 10.1.).

+

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 10.1.).

ProcedureCall = designator [ActualParameters].
 
@@ -896,7 +887,7 @@ ActualParameters = "(" [ExpList] ")" . - + @@ -932,7 +923,7 @@ END

9.5. Case statements

-

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 the statement sequence is executed whose case label list contains the obtained value. If the case expression is of type Int or CHAR, all labels must be integers or single-character strings, respectively.

+

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 the statement sequence is executed whose case label list contains the obtained value. If the case expression is of type Int or Char, all labels must be integers or single-character strings, respectively.

CaseStatement = CASE expression OF case {"|" case} END.
 case = [CaseLabelList ":" StatementSequence].
@@ -958,7 +949,7 @@ case labels must be extensions of T, and in the statements SiTYPE R = RECORD a: Int END;
     R0 = RECORD (R) b: Int END;
-    R1 = RECORD (R) b: REAL END;
+    R1 = RECORD (R) b: Real END;
     R2 = RECORD (R) b: SET END;
     P = POINTER TO R;
     P0 = POINTER TO R0;
@@ -1086,7 +1077,7 @@ FormalType = {ARRAY OF} qualident.
         

Examples of procedure declarations:

PROCEDURE ReadInt(VAR x: Int);
-    VAR i: Int; ch: CHAR;
+    VAR i: Int; ch: Char;
 BEGIN i := 0; Read(ch);
     WHILE ("0" <= ch) & (ch <= "9") DO
         i := 10*i + (ORD(ch) - ORD("0")); Read(ch)
@@ -1247,12 +1238,12 @@ Import = ident [":=" ident].
     IMPORT Texts, Oberon;
     VAR W: Texts.Writer;
 
-    PROCEDURE Write*(ch: CHAR);
+    PROCEDURE Write*(ch: Char);
     BEGIN Texts.Write(W, ch)
     END;
 
     PROCEDURE WriteInt*(x, n: Int);
-        VAR i: Int; a: ARRAY 16 OF CHAR;
+        VAR i: Int; a: ARRAY 16 OF Char;
     BEGIN i := 0;
         IF x < 0 THEN Texts.Write(W, "-"); x := -x END ;
         REPEAT a[i] := CHR(x MOD 10 + ORD("0")); x := x DIV 10; INC(i) UNTIL x = 0;
@@ -1361,6 +1352,6 @@ FormalType = {ARRAY OF} qualident.
 ImportList = IMPORT import {"," import} ";".
 import = ident [":=" ident].
 
- + -- 2.49.0
ReadInt(i)(see Ch. 10)(see Ch. 10)
WriteInt(2*j + 1, 6)