[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