Closed tenko closed 4 months ago
- I guess integer constants is always
LONGINT
, so that the problem with sign extension where the integer value is treated as an unsigned value is not a problem here.
The constants are recognized as follows (output from debug build).
CONST CCHAR*(*Scope:1*) = "A"(*C*)(*Type:CHAR*);
CINT*(*Scope:1*) = 100(*S*)(*Type:SHORTINT*);
CLINT*(*Scope:1*) = -1(*L*)(*Type:LONGINT*);
CREAL*(*Scope:1*) = 1.1(*F*)(*Type:REAL*);
CREALMAX*(*Scope:1*) = 1.79769e+308(*D*)(*Type:LONGREAL*);
CBOOL*(*Scope:1*) = TRUE(*Type:BOOLEAN*);
CSET*(*Scope:1*) = { 0, 31 } (* 2147483649: 10000000000000000000000000000001 *)(*Type:SET*);
CSTR*(*Scope:1*) = "testing123"(*Type:STRING*);
-1
begin a recognized as a LONGINT
might not be ideal.
- The decimal float value
1.1
is inexact represented in base 2 floating point representation and the constant will have different value depending on whether the type isREAL
orLONGREAL
. The Oberon-02 report solves this with creating an additional float format w[h]ere1.1
and1.1E0
isREAL
, while1.1D0
isLONGREAL
.
This is actually already in Oberon-90. I can extend the Scanner accordingly. But I wonder whether it would make sense to lift the decision whether a literal is treated as REAL
or LONGREAL
to Sema as the Scanner has no information on whether the compiler is in Oberon-90, Oberon-2 or Oberon-07 mode.
- The last line commented out triggers the crash here.
Not surprising as I've never put any effort into exported variables, nor have I tested that. I'm sure this can be supported relatively easy by setting the correct linkage type in CodeGen.
- Oberon-07 limit exported constant to integer type. e.g.
REAL
not allowed to be exported. This is probably done to keep the compiler as simple as possible and I do not see any logical reason for that.
Wirth moves in mysterious ways?
- Exported variables in Oberon-07 is read only. This makes sense as it forces the module state to be encapsulated.
This can be supported by adding corresponding checks to Sema.
Excellent.
0FFFFFFFFFFFFFFFFH
is in signed int64 equal to -1
. Out.LongHex(l)
prints FFFFFFFFFFFFFFFF
.
We would have the same problem with sign extension of "hex" values if the constant is inferred as a smaller type.-
export marker for read-only variables.EDIT : Updated 1.
This should be fixed in the latest pull request. The following works for me now (macOS, arm64) as expected with the test modules that you provided, @tenko!
oberon-lang -I.:./include -L./lib -loberon M.Mod
oberon-lang -I.:./include -L./lib -loberon -fenable-main TestImport.Mod
clang -o TestImport TestImport.o M.o -L./lib -loberon -rpath @executable_path/lib
./TestImport
Let me know if it fixes the issue for you too! Thanks!
Excellent. This fixes the issue for me.
While porting some code and unittests from XDS I triggered a crash in the compiler and created a test module:
And a main module:
This creates the following output:
LONGINT
, so that the problem with sign extension where the integer value is treated as an unsigned value is not a problem here.1.1
is inexact represented in base 2 floating point representation and the constant will have different value depending on whether the type isREAL
orLONGREAL
. The Oberon-02 report solves this with creating an additional float format were1.1
and1.1E0
isREAL
, while1.1D0
isLONGREAL
.REAL
not allowed to be exported. This is probably done to keep the compiler as simple as possible and I do not see any logical reason for that.EDIT : Added notes on Oberon-07.