[Oberon] Negative integer literals in Oberon

Oleg N. Cher allot at bk.ru
Fri May 1 12:26:06 CEST 2020


Dear Dave,

After all, the question: is the literal 90909090H considered 64-bit 
unsigned or 32-bit signed? We have four solutions:

1. Consider it as a 64-bit literal, by context. And if we need to 
declare it as a 32-bit literal, we'll write it like this:

   myint := 90909090H - 100000000H;

If we don't like writing code this way, we'll write it differently:

   myint := SYSTEM.VAL(INTEGER, 90909090H);

, quite in the spirit of the Oberon paradigm. So, Artur, this is what I 
suggest you do in your compiler.

2. Consider it as a 32-bit literal. And for 64-bit use the postfix 
modifier like 0FFFFFFFFL, as in Component Pascal. Ofront+ also 
implements this option (in -C mode).

3. Pretend that we have all integer literals of the same size. In this 
case, all the hexadecimal digits allowed as a bitfield value of the 
literal. This way is implemented in most Oberon-07 compilers, which is 
justified by the lack of integer arithmetic of different bits in them. 
(BYTE is a non-arithmeric type in Oberon-07, and its size does not used 
in operations, always casted to INTEGER).

4. Explicitly specifying the constant type, as there was in Turbo Pascal:

CONST MyConst = INTEGER(90909090H);

As in Active Oberon, Delphi and Turbo Pascal. But then it is necessary 
to allow the same (note, non-system) casting in expressions - and rushed.


I would suggest two ways. The non-system way:

   CONST MyConst = 90909090H - 100000000H;

This will be our payment for the fact that there are no unsigned types 
in Oberon. This is a simplification that I think is very useful, but has 
a cost. So now we have all integer constants as signed numbers.

And the system way. Ofront+ supports:

   myint := SYSTEM.VAL(INTEGER, 90909090H);

And in constants too:

   CONST MyConst = SYSTEM.VAL(INTEGER, 90909090H);

The disadvantage here is the compatibility problem, because old sources 
may contain literals that rely on the size of 32 bits. But this is 
mitigated by the fact that Ofront+ supports 5 Oberon dialects, and we 
can choose any of it at our discretion.


dave at brownsmeet.com пишет:
> 
> To be clear - I would like VOC to allow myint32 := 90909090H, but VOC's 
> support of 64 bit literals gets in the way.
> 
> My advice therefore is that if you never plan to support integers of 
> more than 32 bits, go ahead and allow myint := 90909090H.
> 
> If you plan to add support for 64 bit integers later, you will need to 
> work around the problems I described below. I cannot see how to do that, 
> but I would love a solution.
> 
> -- Dave.
> 
> On 2020-04-26 10:14, Joerg wrote:
> 
>> In earlier Oberon versions, variable integer size was supported: 
>> INTEGER and LONGINT. LONGINT is not officially supported in Oberon-07 
>> but the compiler internally declares TYPE LONGINT = INTEGER.
>> The concept of variable integer size is not supported in Oberon-07 
>> anymore. Every INTEGER has one (implementation dependent) size, be it 
>> 16 or 32 or 64 or ...
>>  
>> Syntactically and conceptionally, negative literals do not exist. Only 
>> results of calculations can be negative as they are done signed per 
>> report.
>> CONST neg = -1; is conceptionally the result of subtracting the 
>> literal 1 from 0, and NOT the literal -1.
>>  
>> If you use the hex suffix H to fill up the bits of the underlying 
>> INTEGER, you need to know the INTEGER size and are per definition in 
>> the grey, non-portable, implementation-dependent area of coding
>>  
>> If you use the hex suffix H to specify a (unsigned) 32 bit value for 
>> low level modules that work with 32 bits (on disc or memory or so) the 
>> size of the INTEGER does not matter (as long as it's 32 bits or larger 
>> of course) as your low level module have to treat the passed values 
>> MOD 100000000H anyhow.
>>
>> br
>> Jörg
>>
>>> Am 26.04.2020 um 10:25 schrieb Joerg <joerg.straube at iaeth.ch>:
>>>
>>> Chris
>>>  
>>> 1) b := i;  is allowed, right?
>>> 2) b := i; does not generate a range check, right?
>>> 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.
>>>  
>>> br
>>> Jörg
>>>
>>>> Am 26.04.2020 um 09:28 schrieb 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.
>>>>
>>>>      
>>>>
>>>>     Regards,
>>>>
>>>>     Chris Burrows
>>>>
>>>>     CFB Software
>>>>
>>>>     https://www.astrobe.com
>>>>
>>>>      
>>>>
>>>>     *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
>>>>     *Subject:* [Oberon] Negative integer literals in Oberon
>>>>
>>>>      
>>>>
>>>>     While developing the compiler[1], we got a question
>>>>
>>>>     whether it is possible to write the following:
>>>>
>>>>     PROCEDURE DWord(n: INTEGER);
>>>>     ...
>>>>     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]):
>>>>
>>>>
>>>>     PROCEDURE DWord (n: INTEGER);
>>>>     BEGIN
>>>>       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.
>>>>
>>>>      
>>>>
>>>>     References:
>>>>
>>>>     [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&width=1024&height=768
>>>>     <http://schierlm.github.io/OberonEmulator/emu-wasm.html?image=FullDiskImage&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
>>>>     https://lists.inf.ethz.ch/mailman/listinfo/oberon
>>>>
>>>> --
>>>> Oberon at lists.inf.ethz.ch mailing list for ETH Oberon and related systems
>>>> https://lists.inf.ethz.ch/mailman/listinfo/oberon
>>
>> --
>> Oberon at lists.inf.ethz.ch <mailto:Oberon at lists.inf.ethz.ch> mailing 
>> list for ETH Oberon and related systems
>> https://lists.inf.ethz.ch/mailman/listinfo/oberon
> 
> ------------------------------------------------------------------------
> 
> --
> Oberon at lists.inf.ethz.ch mailing list for ETH Oberon and related systems
> https://lists.inf.ethz.ch/mailman/listinfo/oberon



More information about the Oberon mailing list