Changes in Oberon07
Oberon-07 (Revised Oberon) (Oberon at a glance) NW 20.11.2013 with updates
OBC 3 will have flags
-07to enter Oberon07 mode. Syntax differences (e.g. with RETURN) and changed rules (e.g. about semantics of aggregate value parameters).
-xto enable language extensions.
We have to decide on one of the following goals:
- OBC should implement all Ob07 constructs, possibly with some extensions.
- OBC should accept all legal Ob07 programs. Extensions spoil this if, e.g., they add new keywords, but adding predefined procedures doesn't, provided they can be overridden locally.
- OBC should be able to verify conformance of Ob07. That would mean no extensions enabled by default, and adding a lot of boring checks.
I think (2) is reasonably feasible.
These were found by comparing the Oberon07 report with the original Oberon report
- TRUE and FALSE have become keywords. Implemented: they become keywords with -07 flag, and are otherwise defined as symbolic constants as before.
- Single quoted 'strings' are an Oberon-2 extension not allowed in Oberon or -07. Won't fix
- Case labels must be literal constants, not constant expressions. Won't fix. Note that even negative integer constants are forbiden in the grammar – that's unsurprising in view of the next point.
- Case labels must form a contiguous range based at 0. Won't implement
- SYSTEM provides the following: All consistent, except for COPY
- ADR(v) – address of variable v.
- SIZE(T) – size of type in bytes.
- BIT(a, n) – bit n of mem[a].
- GET(a, v) and PUT(a, x) for any basic type.
- COPY(src, dst, n) copies n words (or n bytes?). Renamed from SYSTEM.MOVE; I'm taking n as a number of bytes to copy
- Possibly VAL(T, x).
- ARRAY OF T is no longer syntactically a type, except in formal parameter declarations. Caught by semantic checks
- LONG and SHORT have disappeared. Implemented
Omissions and Restrictions
- No access to variables in outer procedures. Won't change.
- This has two compatibility implications. If variables declared in an outer procedure shadow global ones, then perhaps Wirth's compiler makes the name refer to the global variable within the inner procedure. And presumably this change means that inner procedures are assignable to procedure variables. The solution to both problems is the same: manually hoist the nested procedure to the global scope where it belongs.
- Data type SHORTINT eliminated. Won't change. I'm keeping SHORTINT (16 bits) and LONGINT (64 bits) and adding BYTE (8 bits unsigned) with implicit conversions between them.
- Type inclusion (no compatibility between INTEGER and REAL). Implemented
- Pointers to records only. Implemented; relaxed by
- Loop and exit statements eliminated. Keywords deleted; relaxed by
- Return statement eliminated (coupled with procedure ending). Done.
- With statement eliminated. Keyword deleted. Not reinstated by
-x; use CASE instead. The WITH statement of O-2 remains if the -07 flag is not given.
- Case statement for extended types added. Implemented
- Imported variables: read-only. Implemented
- Procedure COPY eliminated (replaced by assignment). Done
- Note Section 9.1(4): An open array may be assigned to an array of equal base type.
- Functions CAP, MIN, MAX eliminated. Implemented
- While statement with cascaded conditions. Implemented
- Assignments of arrays and records (replacing COPY). Always allowed
- Set complement (unary minus). Always allowed
- Standard procedures ASSERT, PACK, UNPK, FLOOR, FLT. Done, all but for removing ENTIER. Note that UNPK has a different specification from the C function frexpf. Also FLT causes loss of precision in converting from INTEGER to LONGREAL – at least on Keiko implementations that have single-precision floats (not on vm386). I'm letting the optimiser take care of that.
- Type BYTE as subrange of INTEGER (0 .. 255). BYTE is interassignable with INTEGER.
- Array and record parameters: read-only, unless VAR-parameter. Presumably this means aggregate value parameters are not copied, though such an implementation creates aliasing problems. Implemented, though just for arrays and records; the report seems to say that only basic types (and not pointers) are treated as variables in the procedure body.
- Return clause bound to end of procedure. Implemented.
- ASH(x, n) replaced by LSL(x, n), if n >= 0. LSL and ASR are added (LSR too), and ASH is made invisible
- ASH(x, n) replaced by ASR(x, -n), if n < 0. See previous comment.
- SYSTEM.ROT(n) replaced by ROR(-n). Added ROR.
- HALT(n) replaced by ASSERT(FALSE). Won't implement
- Standard function ENTIER renamed FLOOR. Done
- Single-character strings are assignable to character arrays and to variables of type CHAR. Always allowed
- LONGINT may be synonym to INTEGER
- LONGREAL may be synonym to REAL
Since the notion of type inclusion has vanished, presumably even if different they will be interassignable. I'm keeping them, with silent conversions between all integral and between all real types.