[Oberon] Negative integer literals in Oberon

Chris Burrows chris at cfbsoftware.com
Sun Apr 26 12:51:12 CEST 2020


From: Joerg [mailto:joerg.straube at iaeth.ch] 
Sent: Sunday, 26 April 2020 5:55 PM
To: ETH Oberon and related systems
Cc: chris at cfbsoftware.com
Subject: Re: [Oberon] Negative integer literals in Oberon




1)    b := i;  is allowed, right?


Yes – but the value of i must be in the range 0..255 for the result to be predictable.


2)    b := i; does not generate a range check, right?


Not necessarily. An implementer is not required to generate a range check, but equally they are not prohibited from generating a range check either.


3) i := 511; b := i; 


If 3) doesn’t generate a range check, but you want to be compliant to the report, you implement the assignment as b := i MOD 256;

as any value MOD 256 is between 0..255.


The behaviour is not specified in the report so there is no question of compliance or non-compliance. Hence, the resulting value of b is undefined / unpredictable. Any programmer who assumes a particular result in that case is making a mistake. However, the implementer of the compiler is not required by the report to alert him to that mistake - but he can do if he wants to. 


If the programmer is competent there is no problem because he can write his code in such a way that he gets the answer that he want. If he expects values of i to be outside the range 0..255 and he wants b to be equal to i MOD 256 then he should explicitly code it as:


b := i MOD 256


then there is no doubt about what the result will be no matter what the compiler implementer has decided to do..





Am 26.04.2020 um 09:28 schrieb dave at brownsmeet.com <mailto:dave at brownsmeet.com> :


((Lapsed) VOC maintainer here.)

In both VOC and Oberon 2013, integer literals are parsed in the symbol parser (VOC :OPS.Mod or 2013:ORS.MOD) and stored in the symbol table as signed integer values.

Later, during expression compilation, their size is determined by the magnitude of their signed integer value.

The difference between Oberon 2013 and VOC is the largest integer type, which is 32 bit on Oberon 2013 and 64 bit in VOC.

The special handling that allows a hex literal with top bit set to be treated as a signed value happens at the time the literal is parsed as a symbol independent of what context it is being used in. (Consider e.g. 'CONST mask = 90909090H' - CONST parsing does not know whether this constant will be used in a 64 bit, 32 bit, 16bit or other context.)

VOC and Oberon 2013 do both allow the hex special case top bit set parsing behaviour, the difference being the integer literal size.

Thus VOC accepts myint64 := 9090909090909090H because 9090909090909090H is parsed as a negative 64 bit signed integer.

But VOC does not accept myint32 := 90909090H because 90909090H is parsed as a positive 64 bit signed integer. 

VOC has no way to parse 90909090H as a negative 32 bit signed integer.

 - I did wonder about adding a further suffix letter to indicate the intended size, but I couldn't satisfy myself that any solution was simple enough to be easy to understand.

 - Note that this is independent of VOC's -Ox compatibility setting: that sets the default INTEGER size, not integer literal size - integer literals always support the largest available integer size which is SYSTEM.INT64 aka HUGEINT.)

-- Dave


On 2020-04-25 22:52, Chris Burrows wrote:

It all depends on what size (i.e. number of bits) INTEGER is defined as on the system you are using as to what range of numbers are valid INTEGERs. Since 2011, the range of INTEGER values is no longer defined in the Language Report; it is implementation-dependent. 


In the Project Oberon (2013) RISC5 compiler, INTEGER is 32 bit so 90909090H is a valid INTEGER. Maybe you used the default (-O2) option in VOC? If so, INTEGER is 16 bit so 90909090H would be too large. Make sure you are compiling with the VOC –OC option instead if you want INTEGER to be treated as a 32 bit quantity.


Note that 9090H would be a negative number on a 16-bit INTEGER system but a positive number on a 32-bit INTEGER system.



Chris Burrows

CFB Software



From: Oberon [mailto:oberon-bounces at lists.inf.ethz.ch] On Behalf Of Arthur Yefimov
Sent: Sunday, 26 April 2020 12:38 AM
To: oberon at lists.inf.ethz.ch <mailto:oberon at lists.inf.ethz.ch> 
Subject: [Oberon] Negative integer literals in Oberon


While developing the compiler[1], we got a question

whether it is possible to write the following:

DWord (90909090H)

(where INTEGER is 32-bit).

Some compilers give an error (i.e. VOC), while this works in the

Project Oberon (2013) compiler. This would turn out to be quite convenient,

because the purpose of DWord in our code was to write 4 bytes to the file

given as INTEGER (using little-endian byte order).


DWord has the following implementation (module Generator[2]):

  Files.Write (r, CHR (n MOD 100H));
  Files.Write (r, CHR (n DIV 100H MOD 100H));
  Files.Write (r, CHR (n DIV 10000H MOD 100H));
  Files.Write (r, CHR (n DIV 1000000H))
END DWord;

The Oberon language report does not indicate that literal 90909090H

should be considered an error if INTEGER has 32 bits.

In this experiment, an online RISC emulator[3] was used.



[1] https://github.com/kekcleader/oberon

[2] https://github.com/kekcleader/oberon/blob/master/Mod/Generator.Mod

[3] http://schierlm.github.io/OberonEmulator/emu-wasm.html?image=FullDiskImage <http://schierlm.github.io/OberonEmulator/emu-wasm.html?image=FullDiskImage&width=1024&height=768> &width=1024&height=768


Oberon at lists.inf.ethz.ch <mailto:Oberon at lists.inf.ethz.ch>  mailing list for ETH Oberon and related systems

Oberon at lists.inf.ethz.ch <mailto:Oberon at lists.inf.ethz.ch>  mailing list for ETH Oberon and related systems

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.inf.ethz.ch/pipermail/oberon/attachments/20200426/52f4c99f/attachment.html>

More information about the Oberon mailing list