Spivoxity / obc-3

Oxford Oberon-2 compiler
38 stars 7 forks source link

SYSTEM.VAL does not allow type interpretation #9

Closed Spivoxity closed 5 years ago

Spivoxity commented 5 years ago

Christian Kleinert writes: A usage of SYSTEM.VAL like in

MODULE SysValTest;

IMPORT SYSTEM;

VAR
  byte : SYSTEM.BYTE;
  int : INTEGER;
BEGIN
  byte := SYSTEM.VAL(SYSTEM.BYTE,15);
  int := SYSTEM.VAL(INTEGER, byte);
END SysValTest.

works well under obc 2.9.7, while under 3.0.2 it gives an error:

argument size must match result type in SYSTEM.VAL
Spivoxity commented 5 years ago

The issue is avoiding mayhem when converting between LONGREAL or LONGINT and the smaller types. A better rule is that the input and output types should simply take the same number of words. The compiler can already deal in these quantities for handling parameters.

Spivoxity commented 5 years ago

Christian: Possibly related to this issue, the following code gives the same error on obc 3.0.x, but complies fine under abc 2.9.7 and voc:

PROCEDURE And*(x, y: LONGINT): LONGINT;
BEGIN
  RETURN SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, x) * SYSTEM.VAL(SET, y))
END And;
"LBit.m", line 7: argument size must match result type in SYSTEM.VAL
>   RETURN SYSTEM.VAL(LONGINT, SYSTEM.VAL
Spivoxity commented 5 years ago

That isn't going to give the right result anyway, because * on sets is implemented as 32-bit bitwise AND. So in this case I think the error message is helpful.

You can get the compiler to give this WRONG behaviour without complaint by writing

RETURN LONG(SYSTEM.VAL(INTEGER, SYSTEM.VAL(SET, SHORT(x)) * SYSTEM.VAL(SET, SHORT(Y))))

The bad behaviour is inevitable because the compiler cannot generate 64-bit bitwise AND instructions, and in fact the virtual machine has no such instruction, even if the underlying hardware has it.

For the RIGHT behaviour, it's best to introduce a new primitive with a body written in C. For portability, use get_long and put_long in the body of the primitive.

Spivoxity commented 5 years ago

Christian: Thanks a lot for the info, will fix my code with primitives.

Spivoxity commented 5 years ago

Fixed in 3.0.3