gm2
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: gm2 rejecting a constant statement as variable


From: Alice Osako
Subject: Re: gm2 rejecting a constant statement as variable
Date: Sat, 30 Mar 2024 21:15:21 -0400
User-agent: Mozilla Thunderbird

Gaius Mulley:
Alice Osako <alicetrillianosako@gmail.com> writes:

I am currently intending to work with M2PP (https://github.com/m2sf/m2pp), and for this purpose I have been writing a Makefile to compile all of the
components and build the preprocessor. I have run the configuration script (using the settings for ISO, GNU, POSIX, 32/64) and started preparing the make
targets for the individual sub-modules.

However, I have come across a surprising problem: several constant initializations are being flagged as involving one or more variables. I have confirmed
that the assignments in question are, in fact, constant, but the compiler is saying that they aren't.

For example, the constant declaration:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  BitsInUse =
    ORD(AddressableBits > MaxBits) * MaxBits +
    ORD(AddressableBits <= MaxBits) * AddressableBits;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Gives the following error:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/imp/Hash.mod:34:13: error: In implementation module ‘Hash’: in assignment, cannot assign a variable to a constant ‘BitsInUse’
   34 |   BitsInUse =
      |             ^
src/imp/Hash.mod:34:3: error: designator ‘BitsInUse’ is declared as a CONST
   34 |   BitsInUse =
      |   ^~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

I have confirmed that both AddressableBits and MaxBits are constants, and the application of +, *, and ORD() on constants clearly should be recognized as
constants as well. Indeed, immediately following this initialization is the constant declaration

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  TTP16  = ORD(AddressableBits>16) * 65535 + 1;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

compiles without complaint.
Hi,

(I am assuming that ORD(FALSE) should return zero, and ORD(TRUE)
should return one,
correct

which it clearly is the intended use in this code - in effect, a
pocket ternary _expression_ that only works with numeric values.)

I think this is a compiler error

I noted that the error message does not specify the supposed variable
in question, which would make it harder to debug even if there were a
variable in the assignment.
indeed, I've fixed this locally:

$ gm2 constbool2.mod 
constbool2.mod:8:36: error: In program module ‘constbool2’: the procedure function ‘ORD’ is being called from within a constant _expression_ and therefore the parameter must be a constant, seen _expression_
    8 |    BitsInUse = ORD(AddressableBits > MaxBits) * MaxBits + ORD(AddressableBits <= MaxBits) * AddressableBits;
      |                    ~~~~~~~~~~~~~~~~^~~~~~~~~

but I've seen this fix needs to be applied to most of the standard
procedure functions.  Once this is done and passes the regression tests
I'll push the git changes

Am I missing something? I am not inclined to assume that this is a
compiler fault, but if it isn't, I am not certain why it would see a
variable in these assignments.
and then move on to the original bug, which is occurring due to the
comparison operator.  The result of the comparison is currently stored
in a variable - which needs to be fixed!

Many thanks for the bug reports - will fix,

You're welcome.

I ran into another issue which I am less certain about. The following declaration

VAR
 
powerOf2 : ARRAY [0..Bitwidth-1] OF CARDINAL;

Gives the following error:

src/imp/CardMath.mod:374:14: error: In procedure ‘IntMaxDecDigitsTable’: circular dependency error found when trying to resolve array
  374 |   powerOf2 : ARRAY [0..Bitwidth-1] OF CARDINAL;
      |              ^~~~~


What is peculiar here is that a) the declarations of powerOf2 and Bitwidth are not circular, and b) this declaration is of module scope, and comes before the beginning of IntMaxDecDigitsTable. For reference, Bitwidth is a constant defined as
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  MaxCardDivPow2Of8   = MAX(CARDINAL) DIV 256;
  MaxCardDivPow2Of16  = MaxCardDivPow2Of8 DIV 256;
  MaxCardDivPow2Of24  = MaxCardDivPow2Of16 DIV 256;
  MaxCardDivPow2Of32  = MaxCardDivPow2Of24 DIV 256;
  MaxCardDivPow2Of40  = MaxCardDivPow2Of32 DIV 256;
  MaxCardDivPow2Of48  = MaxCardDivPow2Of40 DIV 256;
  MaxCardDivPow2Of56  = MaxCardDivPow2Of48 DIV 256;
  MaxCardDivPow2Of64  = MaxCardDivPow2Of56 DIV 256;
  MaxCardDivPow2Of72  = MaxCardDivPow2Of64 DIV 256;
  MaxCardDivPow2Of80  = MaxCardDivPow2Of72 DIV 256;
  MaxCardDivPow2Of88  = MaxCardDivPow2Of80 DIV 256;
  MaxCardDivPow2Of96  = MaxCardDivPow2Of88 DIV 256;
  MaxCardDivPow2Of104 = MaxCardDivPow2Of96 DIV 256;
  MaxCardDivPow2Of112 = MaxCardDivPow2Of104 DIV 256;
  MaxCardDivPow2Of120 = MaxCardDivPow2Of112 DIV 256;

  BW8   = (MAX(CARDINAL) <= 255);
  BW16  = (MaxCardDivPow2Of8 > 0) AND (MaxCardDivPow2Of8 <= 255);
  BW24  = (MaxCardDivPow2Of16 > 0) AND (MaxCardDivPow2Of16 <= 255);
  BW32  = (MaxCardDivPow2Of24 > 0) AND (MaxCardDivPow2Of24 <= 255);
  BW40  = (MaxCardDivPow2Of32 > 0) AND (MaxCardDivPow2Of32 <= 255);
  BW48  = (MaxCardDivPow2Of40 > 0) AND (MaxCardDivPow2Of40 <= 255);
  BW56  = (MaxCardDivPow2Of48 > 0) AND (MaxCardDivPow2Of48 <= 255);
  BW64  = (MaxCardDivPow2Of56 > 0) AND (MaxCardDivPow2Of56 <= 255);
  BW72  = (MaxCardDivPow2Of64 > 0) AND (MaxCardDivPow2Of64 <= 255);
  BW80  = (MaxCardDivPow2Of72 > 0) AND (MaxCardDivPow2Of72 <= 255);
  BW88  = (MaxCardDivPow2Of80 > 0) AND (MaxCardDivPow2Of80 <= 255);
  BW96  = (MaxCardDivPow2Of88 > 0) AND (MaxCardDivPow2Of88 <= 255);
  BW104 = (MaxCardDivPow2Of96 > 0) AND (MaxCardDivPow2Of96 <= 255);
  BW112 = (MaxCardDivPow2Of104 > 0) AND (MaxCardDivPow2Of104 <= 255);
  BW120 = (MaxCardDivPow2Of112 > 0) AND (MaxCardDivPow2Of112 <= 255);
  BW128 = (MaxCardDivPow2Of120 > 0) AND (MaxCardDivPow2Of120 <= 255);

  Bitwidth =
    8*ORD(BW8) + 16*ORD(BW16) + 24*ORD(BW24) + 32*ORD(BW32) +
    40*ORD(BW40) + 48*ORD(BW48) + 56*ORD(BW56) + 64*ORD(BW64) +
    72*ORD(BW72) + 80*ORD(BW80) + 88*ORD(BW88) + 96*ORD(BW96) +
    104*ORD(BW104) + 112*ORD(BW112) + 120*ORD(BW120) + 128*ORD(BW128);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
where BWn is a series of boolean values which gate individual bit markers (AFAICT, anyway).

I can't see how these declarations would be circular.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]