diff --git a/.gitattributes b/.gitattributes index 499fc1e3ee..947ccc5cf5 100644 --- a/.gitattributes +++ b/.gitattributes @@ -13573,6 +13573,7 @@ tests/webtbs/tw24871.pp svneol=native#text/pascal tests/webtbs/tw2492.pp svneol=native#text/plain tests/webtbs/tw2494.pp svneol=native#text/plain tests/webtbs/tw24953.pp svneol=native#text/pascal +tests/webtbs/tw25004.pp svneol=native#text/pascal tests/webtbs/tw2503.pp svneol=native#text/plain tests/webtbs/tw2504.pp svneol=native#text/plain tests/webtbs/tw2514.pp svneol=native#text/plain diff --git a/compiler/pdecsub.pas b/compiler/pdecsub.pas index b01311e9e4..ab0421a509 100644 --- a/compiler/pdecsub.pas +++ b/compiler/pdecsub.pas @@ -1286,10 +1286,6 @@ implementation else MessagePos(pd.fileinfo,type_e_type_id_expected); end; - if (optoken in [_EQ,_NE,_GT,_LT,_GTE,_LTE,_OP_IN]) and - ((pd.returndef.typ<>orddef) or - (torddef(pd.returndef).ordtype<>pasbool8)) then - Message(parser_e_comparative_operator_return_boolean); if (optoken in [_ASSIGNMENT,_OP_EXPLICIT]) and equal_defs(pd.returndef,tparavarsym(pd.parast.SymList[0]).vardef) and (pd.returndef.typ<>undefineddef) and (tparavarsym(pd.parast.SymList[0]).vardef.typ<>undefineddef) then diff --git a/tests/webtbs/tw25004.pp b/tests/webtbs/tw25004.pp new file mode 100644 index 0000000000..6561f34dc3 --- /dev/null +++ b/tests/webtbs/tw25004.pp @@ -0,0 +1,151 @@ +program tw25004; + +{$MODE DELPHI} + +uses + SysUtils; + +type + TExpression = class(TObject) + end; + + TLiteralInteger = class(TExpression) + public + Value: integer; + + constructor Create(Value: integer); virtual; + function ToString(): string; override; + end; + + TVariableReference = class(TExpression) + public + Identifier: string; + + constructor Create(const Identifier: string); virtual; + function ToString(): string; override; + end; + + TBinaryOperator = (boAdd, boGreaterThan); + + TBinaryOperatorExpression = class(TExpression) + protected + function OperatorToString(Operator_: TBinaryOperator): string; + public + Operator_: TBinaryOperator; + Left: TExpression; + Right: TExpression; + + constructor Create(Operator_: TBinaryOperator; Left: TExpression; Right: TExpression); virtual; + destructor Destroy(); override; + function ToString(): string; override; + end; + + TExpressionBuilder = record + public + Expression: TExpression; + + class operator Implicit(Operand: TExpression): TExpressionBuilder; + class operator Implicit(Value: integer): TExpressionBuilder; + class operator Add(const Left: TExpressionBuilder; const Right: TExpressionBuilder): TExpressionBuilder; + class operator GreaterThan(const Left: TExpressionBuilder; const Right: TExpressionBuilder): TExpressionBuilder; + end; + + { TLiteralInteger } + + constructor TLiteralInteger.Create(Value: integer); + begin + inherited Create(); + + Self.Value := Value; + end; + + function TLiteralInteger.ToString(): string; + begin + Result := IntToStr(Value); + end; + + { TVariableReference } + + constructor TVariableReference.Create(const Identifier: string); + begin + inherited Create(); + + Self.Identifier := Identifier; + end; + + function TVariableReference.ToString(): string; + begin + Result := Identifier; + end; + + { TBinaryOperatorExpression } + + constructor TBinaryOperatorExpression.Create(Operator_: TBinaryOperator; Left, Right: TExpression); + begin + inherited Create(); + + Self.Operator_ := Operator_; + Self.Left := Left; + Self.Right := Right; + end; + + destructor TBinaryOperatorExpression.Destroy(); + begin + Left.Free(); + Right.Free(); + + inherited Destroy(); + end; + + function TBinaryOperatorExpression.OperatorToString(Operator_: TBinaryOperator): string; + begin + case Operator_ of + boAdd: + Result := '+'; + boGreaterThan: + Result := '>'; + else + raise Exception.Create('Unknown operator'); + end; + end; + + function TBinaryOperatorExpression.ToString(): string; + begin + Result := Left.ToString() + ' ' + OperatorToString(Operator_) + ' ' + Right.ToString(); + end; + + { TExpressionBuilder } + + class operator TExpressionBuilder.Add(const Left: TExpressionBuilder; const Right: TExpressionBuilder): TExpressionBuilder; + begin + Result := TBinaryOperatorExpression.Create(boAdd, Left.Expression, Right.Expression); + end; + + class operator TExpressionBuilder.Implicit(Operand: TExpression): TExpressionBuilder; + begin + Result.Expression := Operand; + end; + + class operator TExpressionBuilder.GreaterThan(const Left: TExpressionBuilder; const Right: TExpressionBuilder): TExpressionBuilder; + begin + Result := TBinaryOperatorExpression.Create(boGreaterThan, Left.Expression, + Right.Expression); + end; + + class operator TExpressionBuilder.Implicit(Value: integer): TExpressionBuilder; + begin + Result := TLiteralInteger.Create(Value); + end; + +var + Variable1: TExpressionBuilder; + Variable2: TExpressionBuilder; + Formula: TExpressionBuilder; +begin + Variable1 := TVariableReference.Create('a'); + Variable2 := TVariableReference.Create('b'); + Formula := Variable1 + 1 > 5 + Variable2; + if Formula.Expression.ToString() <> 'a + 1 > 5 + b' then + halt(1); + Formula.Expression.Free(); +end.