[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