[fpc-devel] some little errors/notes

Gerhard Scholz gs at g--s.de
Thu May 26 11:18:52 CEST 2005


Hello,

some notes on the compiler:

1.)
I tried to compile the compiler itself ("make win32zip") and found the
following:

a)

the routine packages\extra\winunitsjwawownt16.pas contains the line (#55)
  {$WARN SYMBOL_PLATFORM OFF}
which is not recognized and gives an error.
I made a real comment out of it:    {   $WARN SYMBOL_PLATFORM OFF}

b)

the unit parabase.pas in the compiler, line# 240
    function ParaNrCompare(Item1, Item2: Pointer): Integer;
...
      begin
        Result := I1.paranr - I2.paranr ;
      end ;
gives an overflow (I compiled the whole thing with range check on, stack
check on, overflow check on, and then the compler dies while compiling
itself!!)

I then replace the assignment with:
   {$ifopt Q+}
     {$define OVERFLOW_ON}
     {$Q-}
   {$endif}
   {$ifopt R+}
     {$define RANGE_ON}
     {$R-}
   {$endif}
        Result:=I1.paranr-I2.paranr;
   {$ifdef OVERFLOW_ON}
     {$Q+}
     {$undef OVERFLOW_ON}
   {$endif}
   {$ifdef RANGE_ON}
     {$R+}
     {$undef RANGE_ON}
   {$endif}

This still is a hack, a cleaner solution would be:
    Result := sign ( longint ( l1.paranr ) - longint ( l2.paranr ) ) ) ;

With these modifications the "make win32zip" comes to an end and produces a
lot of ZIP-files.

I wasn' able to find out why the compiler is compiled three times, the RTL
even four times.

2.)

a)

The power operator (**) seems to be integrated in the compiler, but only
partial. I didn't find a description of it in the Reference Manual.

I tried a little program
  PROGRAM x;
    BEGIN
     WRITELN ( 1 ** 2 ) ;
   END.
which died with the runtime error 221 (I didn't find a description of this
error, either).

Obviously the operator(s) are defined in the unit math, with a USES MATH the
program runs.

Without the MATH unit the routine SYSTEM_starstar$VARIANT$VARIANT$$VARIANT
is called, which seems not to work.

There are some optimizations for the power operator in nadd.pas (only for
REAL ** REAL, not for INT ** INT). But since the operator is overloaded,
this code is not reached...

There is missing an operator overload for REAL ** INT, which could be
handled more optimized than converting it to REAL ** REAL.


b)

in pexpr.pas there is a declaration:

      operator_levels:ARRAY[Toperator_precedence] OF SET OF ttoken=
            [_PLUS,_MINUS,_OP_OR,_PIPE,_OP_XOR],
            [_CARET,_SYMDIF,_STARSTAR,_STAR,_SLASH,

_OP_AS,_OP_IS,_OP_AND,_AMPERSAND,_OP_DIV,_OP_MOD,_OP_SHL,_OP_SHR],
            [_STARSTAR] );

The _STARSTAR_ occurs two times in that sets; I assume the first occurence
is a typing error.

c)

Operators of same precedence are evaluated from left to right:
        a - b + c - d
    means:
        ( ( a - b ) + c ) - d
This follows the "natural" precedence of mathematical formulas. But with the
power operator the "natural" precedence is from right to left:
        a ** b ** c ** d
    normally means:
        a ** ( b ** ( c ** d ) )
The FP compiler evaluates a ** b ** c ** d as:
        ( ( a ** b ) ** c ) ** d
This should be changed to the "natural" behaviour. Other programming
languages (like FORTRAN; if I remember correctly, also the old ALGOLs)
follow the right-to-left-scheme (for ** only, of course).

This can be implemented by (in PEXPR.PAS, about line# 2440):

old code:
      IF pred_level=highest_precedence THEN
        p2:=factor(False)
      ELSE
        p2:=sub_expr(Succ(pred_level),True);

new code:
      IF pred_level=highest_precedence THEN
{!!}    p2:=sub_expr(pred_level,True)
      ELSE
        p2:=sub_expr(Succ(pred_level),True);


That's all for today.

Greetings

Gerhard





More information about the fpc-devel mailing list