[Oberon] Negative integer literals in Oberon

Joerg joerg.straube at iaeth.ch
Fri May 1 12:41:07 CEST 2020


A crux with all these solution is: you have to know the register size of the underlying system, else your code will not even compile.
ASSERTs to find the register size does not help, as 100000000H will not compile on a strict Oberon compiler on a 32bit machine.

You need either an Oberon language clarification for hex nitation, or a compiler that ignores overflows when parsing hex notation.

br
Jörg

> Am 01.05.2020 um 12:26 schrieb Oleg N. Cher <allot at bk.ru>:
> 
> 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
> 
> --
> 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