### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

### Author Topic: Cannot compile this unit (error: argument cannot be assigned to)  (Read 514 times)

#### CandyMan30

• New Member
• Posts: 12
##### Cannot compile this unit (error: argument cannot be assigned to)
« on: July 26, 2022, 10:38:46 pm »
unit fv2RectHelper;

{\$mode delphi}{\$H+}

interface

uses
Classes, windows;

type
{ TPointHelper }

TPointHelper = record helper for TPoint
function IsEmpty:Boolean;
function Equals(P1:TPoint):Boolean;
Function SubStract(P1:TPoint):TPoint;
Procedure SaveToStream(const S:TStream);
end;

{ TRectHelper }

TRectHelper = record helper for TRect
function A: TPoint;                                { Corner points }
function B: TPoint;                                { Corner points }
FUNCTION IsEmpty: Boolean;
FUNCTION Equals (R: TRect): Boolean;
FUNCTION Contains (P: TPoint): Boolean;
PROCEDURE Copy (R: TRect);
PROCEDURE Union (R: TRect);
PROCEDURE Intersect (R: TRect);
Function Size:TPoint;
PROCEDURE Assign (XA, YA, XB, YB: Integer);
Procedure SaveToStream(const S:TStream);
end;

PROCEDURE CheckEmpty (Var Rect: TRect);

implementation

{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++)
TRect OBJECT METHODS
(+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
PROCEDURE CheckEmpty (Var Rect: TRect);
BEGIN
With Rect Do Begin
If (A.X >= B.X) OR (A.Y >= B.Y) Then Begin       { Zero or reversed }
A.X := 0;                                      { Clear a.x } // ERROR IN THIS LINE
A.Y := 0;                                      { Clear a.y } // ERROR IN THIS LINE
B.X := 0;                                      { Clear b.x } // ERROR IN THIS LINE
B.Y := 0;                                      { Clear b.y } // ERROR IN THIS LINE
End;
End;
END;

{ TPointHelper }

function TPointHelper.IsEmpty: Boolean;inline;
begin
result :=(x=0) and (y=0)
end;

function TPointHelper.Equals(P1: TPoint): Boolean;
begin
result := (x=P1.x) and (y=P1.y);
end;

begin
result.x:=x+P1.x;
result.y:=y+P1.y;
end;

function TPointHelper.SubStract(P1: TPoint): TPoint;
begin
result.x:=x-P1.x;
result.y:=y-P1.y;
end;

begin
end;

procedure TPointHelper.SaveToStream(const S: TStream);
begin
s.WriteDWord(X);
s.WriteDWord(Y);
end;

{ TRectHelper }

function TRectHelper.A: TPoint;
begin
result := TopLeft;
end;

function TRectHelper.B: TPoint;
begin
result := BottomRight
end;

function TRectHelper.IsEmpty: Boolean;
begin
Result := (Left >= Right) OR (Top >= Bottom);      { Empty result }
end;

function TRectHelper.Equals(R: TRect): Boolean;
begin
Result := (Left = R.Left) AND (Top = R.Top) AND
(Right = R.Right) AND (Bottom = R.Bottom);         { Equals result }
end;

function TRectHelper.Contains(P: TPoint): Boolean;
begin
result := (P.X >= Left) AND (P.X < Right) AND
(P.Y >= Top) AND (P.Y < Bottom);                   { Contains result }

end;

procedure TRectHelper.Copy(R: TRect);
begin
TopLeft := R.Topleft;                                          { Copy point a }
Bottomright := R.BottomRight;                                          { Copy point b }
end;

procedure TRectHelper.Union(R: TRect);
begin
If (R.Left < Left) Then Left := R.Left;               { Take if smaller }
If (R.Top < Top) Then Top := R.Top;                   { Take if smaller }
If (R.Right > Right) Then Right := R.Right;           { Take if larger }
If (R.Bottom > Bottom) Then Bottom := R.Bottom;       { Take if larger }
end;

procedure TRectHelper.Intersect(R: TRect);
begin
If (R.Left > Left) Then Left := R.Left;               { Take if larger }
If (R.Top > Top) Then Top := R.Top;                   { Take if larger }
If (R.Right < Right) Then Right := R.Right;           { Take if smaller }
If (R.Bottom < Bottom) Then Bottom := R.Bottom;       { Take if smaller }
CheckEmpty(Self);                                     { Check if empty }
end;

begin
end;

{--TRect--------------------------------------------------------------------)
Grow -> Platforms DOS/DPMI/WIN/OS2 - Checked 10May96 LdB
(---------------------------------------------------------------------------}
begin
CheckEmpty(Self);                                     { Check if empty }
end;

function TRectHelper.Size: TPoint;
begin
Result := BottomRight.Substract(TopLeft);
end;

{--TRect--------------------------------------------------------------------)
Assign -> Platforms All - Checked 10May96 LdB
(---------------------------------------------------------------------------}
procedure TRectHelper.Assign(XA, YA, XB, YB: Integer);
begin
Left := XA;                                           { Hold Left value }
Top := YA;                                            { Hold Top value }
Right := XB;                                          { Hold Right value }
Bottom := YB;                                         { Hold Bottom value }
end;

begin
end;

procedure TRectHelper.SaveToStream(const S: TStream);

begin
TopLeft.SaveToStream(s);
Size.SaveToStream(s);
end;

end.

#### lainz

• Hero Member
• Posts: 4066
##### Re: Cannot compile this unit (error: argument cannot be assigned to)
« Reply #1 on: July 26, 2022, 11:59:02 pm »
Quote
A.X := 0;                                      { Clear a.x } // ERROR IN THIS LINE
A.Y := 0;                                      { Clear a.y } // ERROR IN THIS LINE
B.X := 0;                                      { Clear b.x } // ERROR IN THIS LINE
B.Y := 0;                                      { Clear b.y } // ERROR IN THIS LINE

Try this:

Code: Pascal  [Select][+][-]
1. A := Point(0,0);
2. B := Point(0,0);

Edit. It will not work because A and B are functions

Maybe this works:

Code: Pascal  [Select][+][-]
1. TopLeft := Point(0,0);
2. BottomRight := Point(0,0);
« Last Edit: July 27, 2022, 01:00:00 am by lainz »
lainz.github.io

#### PascalDragon

• Hero Member
• Posts: 4872
• Compiler Developer
##### Re: Cannot compile this unit (error: argument cannot be assigned to)
« Reply #2 on: July 27, 2022, 08:58:37 am »
First of, please use [ code=pascal ][ /code ] tags (and maybe only include the relevant parts, namely the declarations and implementations of the methods involved).

Second, A and B are methods, they return a copy of TopLeft and BottomRight. The compiler does not allow you to change this temporary copy, because this code simply can't be right.

So either use TopLeft and BottomRight directly as lainz suggested or introduce a property with both a getter and setter, though you'll still not be able to use your code as is, but instead you'll have to use Point(0, 0) (as lainz suggested as well), because otherwise you'd work on a temporary variable as well.